Ullrich, the 1997 Tour winner who has finished second four times, blitzed his way over the 47-kilometre time trial between Gaillac and here to bag his first Tour stage since 1998.
Armstrong retained the race leader's yellow jersey by a whisker but took a moral battering after finishing in second place at over a minute and a half behind the speedy German.
In the general classification Ullrich moved up from over two minutes behind Armstrong to now being only 34sec adrift -- a margin which hints at images of the two re-enacting their classic battles on the Tour in 2001.
But after admitting he'd made the basic but costly mistake of not drinking enough water for the hilly trek in the hottest-ever day on the Tour so far, the 31-year-old American threw down the gauntlet to his challengers.
"Jan had a great day but don't forget that he's rarely beat me in a time trial on the Tour de France," Armstrong said defiantly before conceding that he spent a hellish day in the saddle.
"Maybe it was too hot for me. I suffered," added Armstrong, who had called Friday's time trial the most important time trial in his Tour career.
"I didn't feel so good on the (last) climb. There was a moment where I felt like I was going backwards. I felt thirsty throughout the stage and it was the thirstiest I've ever felt in a time trial."
Armstrong's struggle was understandable. Minutes before Ullrich rode off the ramp, the temperature at ground level hit an incredible 61 degrees Celsius (141 F) -- the hottest temperature on the Tour since it was first recorded in 1996.
But as of Saturday, when the race heads into the Pyrenees for four days of climbing and the possibility of a thunderstorm on Sunday, Armstrong said it wouldn't be his job to go looking for the yellow jersey.
"It's not my responsibility to attack (in the mountains). If they attack then I'll follow, or at least try to," added Armstrong who said that even the thought of taking the race right down to the wire does not faze him.
"Right now I'm leading the race. I've got 34 seconds (over Ullrich) and if we started the second time trial in Nantes (the penultimate stage) with the same I wouldn't lose sleep."
Brave words, especially given the possibility that Ullrich could produce a repeat of Friday's performance where he took over a minute and a half from his rival.
However, at least on paper, Armstrong can afford to be confident.
The 31-year-old Texan's team, as he recalled, are probably the strongest in the race -- an absolute must in the mountains where good climbers can help chase down and tire the main contenders.
Ullrich's Bianchi team, most of whom followed him from the doomed Coast outfit, are less designed for the heady ascents of the Pyrenees.
And Armstrong, who looked perplexed at having lost out to his long-time rival, said the damage to his race standings was minimal.
"I don't feel too great about coming second, but it's not a disaster. Jan had a great time trial and I think he's now a favorite for the 'Grande Boucle.'
"There's four tough days in the Pyrenees to come and I think I've got the strongest team in the race, which hasn't finished yet. We're just going to have to be prepared in the mountains."
Ullrich, who did not take part in the race last year because of injury and seems to be reveling in his comeback after a testing year, left his habitually reserved side behind as he savored his win.
"I think I've got the real Ullrich back," said the German, who has been at three teams in the space of a year, completed a six-month ban for a drugs-taking incident in a disco and seen the birth of a baby daughter.
"I'm here really to train with a view to next year's Tour but of course I'm still very happy to have beat Lance Armstrong.
"Everything's possible. There's four very hard days in the mountains coming so we'll see what happens."
Alexandre Vinokourov, who started the day in second place 21sec behind Armstrong, came in third place at 2:06 behind Ullrich and admitted the race was still on.
"Ullrich was just unstoppable today," said the 29-year-old Kazakh, who won his first stage on the Tour in Gap a few days ago.
"And I'm pretty happy that I only lost 30 seconds to Armstrong."
Stage 12 results, top 15 (Gaillac - Cap'Decouverte, 47km)
1. Jan Ullrich (GER/BIA) 58min 32sec
(average: 48.178 kph)
2. Lance Armstrong (USA/USP) at 1:36
3. Alexandre Vinokourov (KAZ/TEL) 2:06
4. Haimar Zubeldia (SPA/EUS) 2:40
5. Tyler Hamilton (USA/CSC) 2:43
6. Uwe Peschel (GER/GRL) 3:26
7. David Millar (GBR/COF) 3:55
8. Inigo Chaurreau (SPA/A2R) 4:01
9. David Plaza (SPA/BIA) 4:37
10. Santiago Botero (COL/TEL) 5:00
11. Francisco Mancebo (SPA/BAN) 5:00
12. Iban Mayo (SPA/EUS) 5:03
13. Georg Totschnig (AUT/GRL) 5:06
14. Denis Menchov (RUS/BAN) 5:15
15. Laszlo Bodrogi (HUN/QST) 5:25
Stage 12 overall standings, top 15:
1. Lance Armstrong (USA/USP) 50hr 16min 45sec
2. Jan Ullrich (GER/BIA) at 0:34
3. Alexandre Vinokourov (KAZ/TEL) 0:51
4. Tyler Hamilton (USA/CSC) 2:59
5. Haimar Zubeldia (SPA/EUS) 4:29
6. Iban Mayo (SPA/EUS) 4:29
7. Francisco Mancebo (SPA/BAN) 5:01
8. Ivan Basso (ITA/FAS) 6:49
9. Denis Menchov (RUS/BAN) 7:24
10. Christophe Moreau (FRA/C.A) 7:55
11. Roberto Heras (SPA/USP) 8:24
12. Georg Totschnig (AUT/GRL) 8:28
13. Manuel Beltran (SPA/USP) 9:10
14. David Millar (GBR/COF) 9:34
15. Roberto Laiseka (SPA/EUS) 9:43