The 24-year-old Dutchman controlled a tactical race from pole position through three safety car interventions and resisted intense late pressure from Ferrari’s Carlos Sainz to win by under a second.
Seven-time world champion Lewis Hamilton, who on Friday declared his car as "undriveable", came home third for Mercedes to claim his second podium of a difficult season ahead of team-mate George Russell in fourth.
It was Verstappen’s first Canadian victory in his 150th career start, his sixth this year and the 26th of his career, hoisting him 46 points clear of his rivals in the championship.
"I was giving it everything," said Verstappen. "But so was Carlos. He was pushing, charging, pushing, charging. Naturally, it’s easier to charge with DRS! I had fun today."
Sainz said: "We were quicker, faster all race, but it's difficult to overtake round here. I'm particularly happy with the race pace and with the pressure we put on Max."
Hamilton, a record seven-time winner in Montreal, cheered the big crowd – part of a weekend attendance of 338,000 – and said he was "overwhelmed to get third place. It's been quite a battle, but we've never given up. I've been inspired by my crew."
Ferrari's Charles Leclerc, who started at the back of the grid after taking a penalty for a new engine, finished fifth ahead of Esteban Ocon of Alpine.
Valtteri Bottas and his Alfa Romeo team-mate Zhou Guanyu were later promoted to seventh and eighth after Fernando Alonso in an Alpine was penalised five seconds for his defending against Bottas.
The Spaniard slipped to ninth with Lance Stroll 10th for Aston Martin.
After Saturday's deluge, the race began with a mixed-up 'wet' grid – with Leclerc, Perez and several others out of their normal race positions -- as Verstappen made a clean start from his 15th pole position to take control.
Behind him, Kevin Magnussen made a dazzling departure from fifth to challenge Hamilton, but the Briton resisted and retained fourth as the order settled, Russell making his move early to pass Mick Schumacher for seventh.
On lap three, Sainz passed Alonso, who had been unable to deliver the attacking start he promised, to take second and begin his pursuit of Verstappen.
Perez suffered ill-luck on lap nine when, battling in midfield after starting 13th, his Red Bull lost drive at Turn 13.
"I've lost the engine, man," he told the team as a Virtual Safety Car (VSC) was deployed and Verstappen and Hamilton pitted promptly to switch from mediums to hards.
Seeking his first F1 victory, Sainz pulled clear at the front as Verstappen eased past Alonso, with a DRS move, to take second by lap 18.
A second VSC on lap 20, when Schumacher pulled up and retired at Turn 13 after his highest ever grid position of sixth. It appeared his Haas car had suffered a power failure.
Sainz also pitted, re-joining third ahead of Hamilton – with Verstappen back in the lead ahead of Alonso, who did not pit.
Alpine's reluctance to pit Alonso, still on his original mediums, resulted in Hamilton making an easy pass for third on lap 25.
The two-time champion finally came in after 29 laps and re-joined eighth behind Leclerc, who was struggling on old tyres to pass Ocon.
By mid-distance, Verstappen led Sainz by 7.5 seconds with Hamilton third, a further nine seconds adrift.
A lap later Verstappen made his second stop, emerging just behind Hamilton who pitted again on lap 45, gifting Russell third place, briefly, before he too came in.
Sainz led again, 7.5 seconds ahead of Verstappen, with 20 laps to go when Yuki Tsunoda crashed his Alpha Tauri at Turn Two and a full Safety Car was deployed.
Sainz pitted, followed by both Alpines and Bottas, all opting for mediums.
Verstappen regained the lead, but faced a close scrap with the Spaniard when the action resumed, after a 10-minute delay, with a final dash to the flag.