The visitors began the day in the bottom three but Lucas Perez poked in from close range just after half-time to boost their survival prospects.
This was Barca’s first La Liga loss since 4 December, ending a 15-match unbeaten league run.
Second-placed Barca trail Real Madrid by 15 points with seven games left.
Any hopes the Catalans retained of derailing their great rivals’ bid for a 35th top-flight title were slim before the visit of Cadiz, but this result will serve as a reminder of the gulf between Spain’s dominant teams.
Barca have been resurgent under Xavi since his appointment as manager in November and even thrashed the league leaders.
But the Nou Camp club have endured a chastening week, with this defeat coming five days after they were beaten at home by Eintracht Frankfurt and eliminated from the Europa League semi-finals.
January’s Premier League signings Pierre-Emerick Aubameyang and Adama Traore were left out of the starting XI against Cadiz before being brought on as the home side sought an equaliser, but the visitors held firm.
Victory takes Cadiz two points clear of the relegation zone with six matches left.