Match ends, Millwall 1, Bristol City 2.
Bristol City came from behind to win at Millwall and keep their slim Championship play-off hopes alive.
The Lions, already certain of their second-tier status for next season after Rotherham United's relegation was confirmed on Saturday, went in front through Lee Gregory's smart finish before half-time.
Shaun Williams then had the chance to double Millwall's lead from the spot after Max O'Leary fouled Gregory, but the City goalkeeper atoned for his mistake by saving the penalty.
That sparked a remarkable turnaround from the Robins, who levelled through Jamie Paterson's curling free-kick and then secured an unlikely victory when Famara Diedhiou fired into the bottom corner.
Bristol City, beaten at home by Derby County on Saturday, are now one point behind the sixth-placed Rams and seventh-placed Middlesbrough.
Frank Lampard's side remain strong favourites to secure sixth spot, however, with a game in hand against Swansea City to follow on Wednesday.
When Williams was presented with the opportunity to put Millwall 2-0 up from 12 yards with less than 20 minutes left, City's chances of taking the play-off race into the final weekend looked to have been completely extinguished.
But O'Leary's one-handed save low to his right gave the visitors a lifeline and Paterson's free-kick moments later turned the game on its head.
Diedhiou, without a goal in three games, then fired the Robins ahead with nine minutes remaining and Lee Johnson's men held on to win.
- 3MeredithSubstituted forMcLaughlinat 78'minutes
- 6WilliamsSubstituted forElliottat 87'minutes
- 32HuntSubstituted forPisanoat 30'minutesSubstituted forTaylorat 62'minutes
- 12WalshBooked at 45minsSubstituted forPalmerat 45'minutesBooked at 58mins
- 8BrownhillBooked at 24mins
- Andy Madley
- Shots on Target
Second Half ends, Millwall 1, Bristol City 2.
Andreas Weimann (Bristol City) wins a free kick in the defensive half.
Foul by Mahlon Romeo (Millwall).
Lloyd Kelly (Bristol City) wins a free kick in the defensive half.
Foul by Steve Morison (Millwall).
Attempt missed. Adam Webster (Bristol City) right footed shot from outside the box is too high.
Attempt saved. Andreas Weimann (Bristol City) right footed shot from a difficult angle on the right is saved in the centre of the goal. Assisted by Kasey Palmer with a through ball.
Substitution, Millwall. Tom Elliott replaces Shaun Williams.
Corner, Bristol City. Conceded by Mahlon Romeo.
Goal! Millwall 1, Bristol City 2. Famara Diedhiou (Bristol City) right footed shot from the centre of the box to the bottom left corner. Assisted by Jamie Paterson.
Attempt blocked. Lee Gregory (Millwall) right footed shot from the centre of the box is blocked. Assisted by Steve Morison with a headed pass.
Foul by Adam Webster (Bristol City).
Jake Cooper (Millwall) wins a free kick in the attacking half.
Hand ball by Kasey Palmer (Bristol City).
Substitution, Millwall. Conor McLaughlin replaces James Meredith.
Goal! Millwall 1, Bristol City 1. Jamie Paterson (Bristol City) from a free kick with a right footed shot to the bottom right corner.
Matty Taylor (Bristol City) wins a free kick in the attacking half.
Foul by James Meredith (Millwall).
Penalty saved! Shaun Williams (Millwall) fails to capitalise on this great opportunity, left footed shot saved in the bottom left corner.