Match ends, Charlton Athletic 3, Bristol City 2.
Macaulay Bonne scored twice before setting up Alfie Doughty's late winner as Charlton beat Bristol City to claim their first victory in 12 games.
Bonne's first goal gave the home side the lead just before the break, but half-time substitute Niclas Eliasson immediately crossed for Andreas Weimann to head City's equaliser.
Eliasson then fired City ahead on the hour mark - only for Bonne to restore parity by lashing a left-foot volley past Dan Bentley.
The Charlton forward then raced clear seven minutes from time and crossed for Doughty, who scrambled his first senior goal over the line to secure the points.
The win lifted Charlton to 16th place in the table, while City - who have now lost four games in a row - drop to 10th.
After a tame opening to the game, Bonne broke the deadlock five minutes before half-time, chasing Albie Morgan's long ball and capitalising on Bentley's hesitation to lob him from the edge of the box.
However, City boss Lee Johnson made a double change at the break, sending on Jay Dasilva and Eliasson - and the latter took only 45 seconds to make an impact.
Racing down the right flank, the Swede cut back inside and delivered a left-foot cross onto the head of Weimann, who glanced home his eighth goal of the campaign.
Although Naby Sarr's header hit the bar for Charlton, Eliasson appeared to have completed the turnaround when he put City 2-1 up with a close-range finish beyond Dillon Phillips.
But Bonne had other ideas, playing a one-two with Lyle Taylor before holding off Tomas Kalas to rifle in a 78th-minute equaliser.
And Bonne's run and cross five minutes later enabled midfielder Doughty, who only turned 20 just before Christmas, to snatch Charlton's winner at the second attempt.
Charlton manager Lee Bowyer told BBC London:
"Our games aren't dull. How many times have we scored two or more goals this season? It's getting silly - I'd love a 1-0 at the moment.
"There have been games where we've deserved the three points and they've not come our way. Today, did we deserve the three points? I thought it was quite an even game.
"We went 2-1 behind without really doing anything wrong, but that's the difference in this league - you get punished. But the players just kept going and going, their will to win is great.
"Bristol City are a team that should be in the top six this season. They're a good side - look at the people they're bringing off the bench - so let's not underestimate what we've just done."
Bristol City boss Lee Johnson told BBC Bristol:
"I'm disappointed that we've conceded three goals. Our defending wasn't good enough today, both in terms of individuals, and the way we defended the three goals was sloppy.
"I think the two centre-halves need to organise that little bit better, given the experience they've got. They're very good players and it should be a lovely balance - unfortunately today it wasn't.
"The changes I made at half-time, the boys came in and did well - Jay Dasilva, after a long time out, and Niclas Eliasson made an instant impact. I think Jay showed his quality in the second half.
"Niclas was good when he came on and that's what we want on a consistent basis. It is a dilemma, to play Niclas or not, and when he turns it on and is fed in good areas, there aren't many more dangerous in the division. When he doesn't, that often leaves us having to over-defend."
- 19MorganBooked at 85minsSubstituted forPearceat 86'minutes
- 4OshilajaBooked at 90mins
- 11GallagherSubstituted forPurringtonat 52'minutes
- 45DoughtySubstituted forSollyat 90+2'minutes
- 17BonneBooked at 32mins
- 2HuntSubstituted forEliassonat 45'minutes
- 8BrownhillBooked at 18mins
- 42MassengoSubstituted forO'Dowdaat 83'minutes
- 25RoweSubstituted forDasilvaat 45'minutes
- Keith Stroud
- Shots on Target
Second Half ends, Charlton Athletic 3, Bristol City 2.
Attempt saved. Andreas Weimann (Bristol City) header from the centre of the box is saved in the bottom right corner. Assisted by Josh Brownhill with a cross.
Corner, Bristol City. Conceded by Tom Lockyer.
Attempt blocked. Ádám Nagy (Bristol City) right footed shot from the centre of the box is blocked.
Adedeji Oshilaja (Charlton Athletic) is shown the yellow card.
Ádám Nagy (Bristol City) wins a free kick on the right wing.
Foul by Adedeji Oshilaja (Charlton Athletic).
Foul by Tomas Kalas (Bristol City).
Lyle Taylor (Charlton Athletic) wins a free kick on the left wing.
Attempt missed. Andreas Weimann (Bristol City) left footed shot from the centre of the box is high and wide to the left.
Substitution, Charlton Athletic. Chris Solly replaces Alfie Doughty.
Andreas Weimann (Bristol City) wins a free kick on the right wing.
Foul by Naby Sarr (Charlton Athletic).
Substitution, Charlton Athletic. Jason Pearce replaces Albie Morgan.
Hand ball by Ádám Nagy (Bristol City).
Albie Morgan (Charlton Athletic) is shown the yellow card.
Niclas Eliasson (Bristol City) wins a free kick on the right wing.
Foul by Alfie Doughty (Charlton Athletic).
Substitution, Bristol City. Callum O'Dowda replaces Han-Noah Massengo.