Diego Simeone's side surrendered a 15-game unbeaten run as the Brazilian fired home an 88th-minute volley.
A draw would have seen Atletico climb above Barcelona to the summit going into the 10-day winter break.
But they had to hold on after losing skipper Gabi Fernandez to two yellows cards in the space of five minutes early in the second half.
In a sometimes bad-tempered encounter, the visitors were up against it from the moment Fernandez was cautioned for a foul, then ordered in the 56th minute after committing a handball near the halfway line.
Charles saw two first-half chances saved by Atletico keeper Jan Oblak in a game short on clear openings.
But the Brazilian had the final say, finding the net with the aid of a deflection off defender Diego Godin for his sixth goal of the season.
Barcelona have a game in hand after being without a domestic fixture due to their involvement in the Club World Cup final against River Plate.
Atletico Madrid missed a chance to go top of La Liga after falling to a late winner from Malaga striker Charles.