Match ends, Reading 1, Millwall 2.
Reading fell further behind their Championship promotion rivals as Millwall's late fightback condemned them to back-to-back home defeats.
The Royals went ahead in bizarre fashion when Alfa Semedo challenged for Lions keeper Bartosz Bialkowski's throw and the ball cannoned into an unguarded net from 50 yards.
Millwall had struggled to create clear chances before Tom Bradshaw's scuffed effort fell to Matt Smith, who slotted past Rafael Cabral.
Ovie Ejaria's deflected shot hit the bar for Reading, but Mason Bennett looped Scott Malone's cross over Cabral to stun the hosts.
Reading were looking to prevent the gap further widening to the automatic promotion spots, but a run of one win in five matches has left them fifth and nine points adrift of second-placed Brentford.
A subdued start from the hosts allowed Millwall to make the early running as George Evans headed Malone's cross against the bar before Semedo's bizarre opener.
The lead was almost doubled when Michael Olise's defence-splitting pass put Lucas João through, but Bialkowski's superb low save denied him a 20th goal of the season.
Reading struggled to pick up momentum and build on their lead as the visitors showed plenty of intent without threatening Cabral's goal.
The Lions channelled most of their attacks through Malone on the flanks, and the tactic paid off as his delivery into the box ultimately led to the equaliser before putting a cross on Bennett's head for the winner.
Resurgent Millwall, who have earned 23 of their 38 points on the road this season, extended their unbeaten league run to six matches and climbed to 13th, eight points outside the play-off places.
- 33Cabral Barbosa
- 29HolmesSubstituted forYiadomat 76'minutes
- 15GibsonSubstituted forBaldockat 87'minutes
- 28LaurentSubstituted forRichardsat 87'minutes
- 18Lucas João
- 2Pontes Esteves
- 4HutchinsonBooked at 65mins
- 19WoodsSubstituted forMitchellat 90+3'minutes
- 6WilliamsSubstituted forJ Wallaceat 45'minutesBooked at 90mins
- 8ThompsonSubstituted forSmithat 63'minutes
- 13ZohoreSubstituted forBradshawat 71'minutes
- 22BödvarssonSubstituted forBennettat 45'minutes
- 7J Wallace
- Andy Woolmer
- Shots on Target
Second Half ends, Reading 1, Millwall 2.
Ovie Ejaria (Reading) wins a free kick in the defensive half.
Foul by Jed Wallace (Millwall).
Attempt blocked. Billy Mitchell (Millwall) right footed shot from the centre of the box is blocked. Assisted by Scott Malone.
Attempt blocked. Omar Richards (Reading) right footed shot from outside the box is blocked. Assisted by Andy Yiadom.
Substitution, Millwall. Billy Mitchell replaces Ryan Woods.
Corner, Reading. Conceded by Jake Cooper.
Michael Olise (Reading) wins a free kick in the attacking half.
Foul by George Evans (Millwall).
Jed Wallace (Millwall) is shown the yellow card for a bad foul.
Omar Richards (Reading) wins a free kick in the attacking half.
Foul by Jed Wallace (Millwall).
Substitution, Reading. Omar Richards replaces Josh Laurent.
Substitution, Reading. Sam Baldock replaces Lewis Gibson.
Attempt missed. Lewis Gibson (Reading) left footed shot from the left side of the box is just a bit too high. Assisted by Michael Olise.
Goal! Reading 1, Millwall 2. Mason Bennett (Millwall) header from the centre of the box to the top right corner.
Foul by Lewis Gibson (Reading).
Jed Wallace (Millwall) wins a free kick in the defensive half.
Attempt missed. Matt Smith (Millwall) header from the centre of the box is just a bit too high. Assisted by Jed Wallace with a cross.