Hamilton appeared on course to take his 92nd career pole but Bottas snatched the spoils at the death, finishing 0.063 seconds ahead of the six-time world champion.
Perez remains sidelined with coronavirus and Hulkenberg was the only driver within one second of the all-conquering Mercedes team.
Max Verstappen took fourth ahead of Renault’s Daniel Ricciardo with Lance Stroll sixth for Racing Point. Sebastian Vettel’s poor form for Ferrari left him in a disappointing 12th.
Hamilton stole an early march on Bottas but a poor first sector on his final run handed the initiative to his team-mate, with the Finn claiming his first pole since the opening round in Austria.
Bottas, who signed a one-year Mercedes contract extension earlier this week, said: “When you are starting from pole you can only aim to win the race.
“The pace is there so the job is to get a good start off the line and go from there.”
Hamilton, 30 points clear of Bottas in the championship, said: “It wasn’t that great but Valtteri did a good job and deserved pole. For me it wasn’t a perfect last lap.”
Hulkenberg qualified 13th last week but failed to start the race following a car failure. He said: “It has been a crazy seven or eight days.
“Last week, we had the high of the comeback and then the low of not starting on Sunday.
“I felt more prepared this week. I am surprised to stand here but there is a big smile on my face.”
Four-time world champion Vettel was lost for words after finishing a lowly 10th here last weekend as his team-mate Charles Leclerc took third.
And on Saturday, Vettel’s troubled year was dealt another sorry blow after he was eliminated in Q2, and is set to start Sunday’s race from 12th on the grid, two positions worse off than last week.
“It was all I had,” said Vettel over the radio. “It was all I could get from this car. I tried.”
Vettel was signed by Ferrari as the man to end their barren run of world championships – one which extends back to Kimi Raikkonen in 2007 – but his Scuderia career is poised to fizzle out with a depressing whimper.
The German is being moved on at the end of the season with Leclerc, who finished eighth, identified as the team’s star of the future.
Lando Norris heads into his second home race in as many weeks in fourth spot in the championship. He will start from 10th after sneaking through to Q3.
Team-mate Carlos Sainz, who will replace Vettel at Ferrari in 2021, finished 13th with Norris 4-1 up on the Spaniard in qualifying trim this term.
George Russell extended his unbeaten qualifying head-to-head with Williams team-mate Nicholas Latifi to 5-0 after he qualified 15th, three places ahead of the rookie Canadian.
Italian Giuseppe Farina drove an Alfa Romeo to victory at Formula One’s first world championship race, here at Silverstone 70 years ago.
But the Italian team will see both their drivers line up on the last row of the grid for Sunday’s landmark round, with Antonio Giovinazzi and Raikkonen 19th and 20th.