The Red Bull driver took the chequered flag 7.5 seconds ahead of his Monegasque rival after a slow burner, rain-delayed race interrupted by two safety car and five virtual safety car periods and called at its two-hour time limit after 59 of 61 laps. Carlos Sainz in the other Ferrari was third.
Perez is, however, under investigation for a safety car infringement.
“I controlled the race,” said the 32-year-old, who started alongside pole-sitter Leclerc on the front row and snatched the lead from him off the line on a wet track.
“The last three laps were so intense.
“I gave everything for the win today,” added Perez who pushed hard in the closing stages to open up enough of a gap to Leclerc to cover off a potential penalty.
The drive, which Perez hailed as his best performance yet, earned him his fourth career win and second this season, with the Mexican also victorious at Monaco in May.
But it also forced teammate Verstappen to delay his title celebrations.
The Dutchman, who had started a furious eighth after being forced to abort his fastest qualifying lap due to a lack of fuel, needed to leave Singapore with a 138 point margin to his closest challenger.
Instead, he now holds a 104 point lead over Leclerc and a 106 point advantage against Perez in the overall standings, with next week’s race in Japan allowing him another shot at clinching a second title.
His seventh place, only his second finish outside the top-three this season, snapped a five-race winning streak for the 25-year-old.
It came after an uncharacteristically scrappy race that saw him drop positions off the line and make an extra pitstop after locking up and running wide while challenging McLaren’s Lando Norris for fourth at the second safety car restart.
“It’s just a very frustrating weekend,” said Verstappen.
“We have five races left and we have a big lead but I want to have a good weekend every single time.”
Leclerc, who had also started on pole but finished second the last time F1 visited Singapore in 2019, was keen to move on to Japan.
“The bad start put us on the back foot and after that it was a really difficult race,” he said.
Norris finished fourth ahead of teammate Daniel Ricciardo.
The pair handed McLaren their best result of the season, which moved them ahead of Alpine into fourth in the constructors’ standings.
Lance Stroll took sixth ahead of Verstappen, with Sebastian Vettel making it two Aston Martin cars in the points with eighth.
Lewis Hamilton, one of the favourites for victory, was only ninth.
The Briton, starting third, made contact with Sainz at the start and was forced wide.
He slotted into fourth but then locked up on fading intermediate tyres and thumped into the barriers.
“The problems that we have with this car are magnified in the rain,” he said.
Only 14 drivers finished Sunday’s race, the start of which was delayed by a little over an hour due to heavy rain.
Among the retirements was Fernando Alonso, with the Spaniard failing to see the chequered flag on a record 350th F1 start.