Hamilton took provisional pole with his first flying lap but failed to improve with his second, but neither Perez nor Red Bull Racing teammate Max Verstappen could capitalise to usurp him.
The Briton whooped with shock when told over team radio that he had done enough to clinch pole, and he paid tribute to his team for the work done to close the performance gap from the previous round in Bahrain.
“The car was already feeling a lot better from the beginning of this weekend,” he said. “Mad respect to the team for the hard work to really narrow down the [performance] window.
“I love the challenge. I think it’s great finally we’ve got the two Red Bulls there.”
Perez was a surprise second-row starter after beginning his second lap with more than a quarter-second deficit, the Mexican leapfrogging barely improving teammate Verstappen to snatch a career-high qualifying position.
He also starts with the soft tyre compared to Hamilton and Verstappen on the medium, which will give him a grip boost off the line.
“The most important thing is we are showing progress,” he said. “We have been improving.
“I think anything can happen tomorrow. We are on a different strategy to Lewis, to Max, so it is going to be interesting to see what we can do.”
Verstappen was downbeat to qualify third and just 0.087 seconds shy of pole, but the Dutchman recognised opportunity in having the two Red Bull Racing cars immediately behind the Mercedes.
“Just not a good lap, but you can’t be good every time,” he said. “It’s going to be interesting. We have the two cars on different tyres, so let’s see how that will work out. We’ll try to make it difficult for them [Mercedes].”
Charles Leclerc qualified fourth for Ferrari ahead of AlphaTauri’s Pierre Gasly, the pair both 0.3 seconds off pole.
McLaren teammates Daniel Ricciardo and Lando Norris will start sixth and seventh, though Norris was on track for a top-three result before having his time deleted for driving off the track.
Valtteri Bottas was a disappointing eighth in the second Mercedes after two scrappy laps more than 0.4 seconds off his teammate’s benchmark.
Esteban Ocon will start ninth for Alpine ahead of Aston Martin’s Lance Stroll.
Carlos Sainz was unable to follow teammate Leclerc into the pole shootout and will line up 11th for Ferrari.
Williams drivers George Russell and Nicholas Latifi will start 12th and 14th, with Aston Martin’s Sebastian Vettel between them.
Fernando Alonso qualified 15th for Alpine, the Spaniard outqualified by a teammate for the first time since 2017.
Kimi Raikkonen and Antonio Giovinazzi qualified 16th and 17th for Alfa Romeo ahead of Haas duo Mick Schumacher and Nikita Mazepin.
AlphaTauri rookie Yuki Tsunoda crashed out of Q1 without setting a time, the Japanese driver spinning backwards and into the barriers at the Variante Alta chicane. His car was heavily damaged, but the 20-year-old was returned to the pits unhurt.