Verstappen initially went quickest of the frontrunners, as both Mercedes of Bottas pushed the Dutchman down to third. The two Racing Point cars of Sergio Perez and Lance Stroll looked quick, as they went second and third to go ahead of Verstappen in the standings.
Alfa Romeo's Antionio Giovinazzi went wide at the final corner as he tried to get out of the bottom five, while Daniil Kvyat and Kevin Magnussen were put under investigation for an incident at turn 2.
Kimi Raikkonen got into Q2 for the first time this season, as both Haas and Williams were out at the end of Q1.
Hamilton and Bottas traded times in the opening minutes of Q2, with Hamilton setting a time of 1:16.013 to go quickest in the opening of the session.
Perez was on a flyer before a slip of traction coming through turn ten, leaving him fifth, while Carlos Sainz's time was good enough for fourth on the first run.
Perez and Stroll will start fourth and fifth, as Alexander Albon and Sainz qualified in sixth and seventh.
The two Racing Point cars were first out on track to start Q3 with Perez ahead of Stroll, as Hamilton took provisional pole from teammate Bottas by a tenth of a second.
Charles Leclerc reported strange behaviour from his power unit leaving the pits for his final run in Q3. Bottas just missed out on pole, giving the front spot to Hamilton.
Eighth and ninth went to Lando Norris and Leclerc, while Gasly qualified in tenth.
Bahrain International Circuit - Winter testing