Mercedes maintained its 100% record in qualifying so far in 2020, but faced stiff competition from Red Bull's Max Verstappen, who had topped Q1 and was just adrift of Hamilton at the head of the times in Q2.
Verstappen even led the way after the first runs in Q3, but Bottas prevailed as the Mercedes drivers fired back on their second efforts.
Bottas ended up with the fastest middle sector on his final lap, a 1m25.269s, which put him clear by 0.256s as he shuffled Hamilton down to second, with the world champion ending up with the fastest time in the final sector.
Verstappen started his final lap with the quickest sector one time, but he faded as the lap wore on and he wound up 0.293s adrift of pole.
Both Verstappen and Hamilton went slower in Q3 compared to their laps in the middle segment.
Charles Leclerc stunned Alex Albon to take fourth for Ferrari, with the Red Bull driver knocked down to fifth as a result of the Monegasque racer's last-gasp improvement.
All the leading cars will start tomorrow's race on the softs, despite the Mercedes and Ferrari cars, and Renault's Daniel Ricciardo, experimenting with the medium tyres early in Q2.
Ricciardo qualified sixth in Q3 ahead of his teammate Esteban Ocon, with Lando Norris qualifying eighth ahead of Sergio Perez and Carlos Sainz.
Leclerc's late improvement to set the fifth fastest time in Q1 knocked out his Ferrari teammate Sebastian Vettel, who set a personal best on his final lap in the middle segment but wound up being shuffled down to 11th.
Pierre Gasly and Daniil Kvyat also improved on their final runs in Q2, but they were both knocked out in P12 and P13, while a last-gasp lap from Antonio Giovinazzi gave him 14th place for Alfa Romeo ahead of Haas driver Kevin Magnussen.
In Q1, Hulkenberg, who was always due to travel to the Nurburgring on Saturday to work for German broadcaster RTL before his late call-up to replace the unwell Stroll ahead of qualifying, was out early to learn the track in the Canadian's RP20.
He completed a run of several laps on the softs as soon as the opening segment got under way and spent most of the session at the foot of the times, although he was briefly able to move up to P19 ahead of the final runs in Q1.
Hulkenberg's final lap featured a deep moment at the first corner and brief lock ups on the right front and left front respectively at Turn 6 – the right-hander that runs down towards the hairpin – and on the approach to the final chicane.
He set a personal best but lost time in the final sector and wound up last, 0.204s slower than Alfa Romeo's Kimi Raikkonen.
Romain Grosjean missed the cut after having his best lap of the session – a 1m27.118s – deleted for exceeding track limits at Turn 4 in the shadow of the Mercedes grandstand that overlooks the corner and Turn 1.
The Haas driver was able to set another time in the closing moments but was shuffled down and out ahead of the Williams pair George Russell and Nicholas Latifi, as they finished P17 and P18.
|3||Max Verstappen||Red Bull||1'25.562||0.293|
|5||Alex Albon||Red Bull||1'26.047||0.778|
|9||Sergio Perez||Racing Point||1'26.704||1.435|
|10||Carlos Sainz Jr.||McLaren||1'26.709||1.440|
|14||Antonio Giovinazzi||Alfa Romeo||1'26.936||1.667|
|19||Kimi Raikkonen||Alfa Romeo||1'27.817||2.548|
|20||Nico Hulkenberg||Racing Point||1'28.021||2.752|
|View full results|