至德二年(757)二月,郭子仪率部从洛交进攻冯翊县,继又攻取河东。
唐军既达关中,肃宗也移住凤翔。四月,郭子仪为天下兵马副元帅(元帅为皇子李俶),继续讨伐叛军。
叛军到了长安,“以为得志,日夜纵酒,专以声色宝贿为事,无复西出之意”。这就给唐军收复长安提供了机会。
九月,郭子仪率唐军十五万之众,逼近长安,与叛军十万人相持于长安西香积寺北沣水之东。经过激战,叛军全线崩溃,唐军收复长安。这时,洛阳的叛军统治集团因争权夺利,安禄山已被杀死,其子安庆绪继位称帝。
在唐军继续东进的时候,安庆绪放弃洛阳,北走邺郡(治所在今河南安阳),唐军收复洛阳。
乾元元年(758)九月,肃宗调动九个节度使的数十万兵力进攻安庆绪。
在这些节度使中,郭子仪、李光弼的战功最多,威信最高,肃宗不愿把军权交给他们,所以不设主帅,只命宦官鱼朝恩为观军容宣慰处置使,总揽全局。九节度使围邺,并引漳水灌城,安庆绪不仅遭水灾之苦,而且城中极其缺粮,甚至老鼠也成了贵重食物,一只老鼠可卖四千钱。这正是破城良机,但因兵众无主,无人统一指挥,致使史思明能够从魏州(治所在今河北大名)援邺。史思明截劫自江、淮与汾、晋运粮的舟车,断绝唐军的粮源。
同时,又不断用声东击西的办法袭击唐军,使其处于疲于应付的状态。
乾元二年(759)三月,唐军与史思明军展开激战。正当激战之际,大风忽起,吹沙拔木,天昏地暗,咫尺不辨敌我。一场混战,双方均遭重大损失。
叛军内部又起内哄,史思明杀安庆绪,引兵还范阳,自称大燕皇帝。唐军九节度使各自退回,郭子仪被命为东畿、山东、河东诸道元帅,权知东京留守。后因鱼朝恩嫁罪于人,把邺郡战争失败的责任推给郭子仪,致使肃宗召郭子仪还京,以李光弼为天下兵马副元帅,驻守东京。
九月,史思明再度南下,攻取洛阳。十二月,史思明又派李归仁西攻陕州,被唐军击破。上元二年(761)二月,史思明欲西破潼关,受阻后退回永宁(今河南洛宁)。
这时,叛军内部矛盾又突然激化,史思明长子史朝义利用一些将领对史思明的不满情绪,策动兵变,杀史思明,自己继位称帝。
同时,又派人到范阳杀了与其争夺帝位的异母弟史朝清,还杀了持不同政见者数十人。这种自相残杀,引起大规模的内哄,致使数月之内,范阳有数千人为此而死。
宝应元年(762)十月,新即位的代宗(四月即位)命雍王李适为天下兵马元帅,仆固怀恩为副元帅,继续平定叛军。
唐军东进,很快攻下洛阳。帮助唐军平定叛乱的回纥兵到了东都,大肆烧杀抢掠,死者上万人,大火多日不息。宦官鱼朝恩统率的神策军也把东京、郑州(治所在今河南郑州)、汴州(治所在今河南开封)、汝州(治所在今河南临汝)一带视为贼境,任意掳掠。致使这些地方“比屋荡尽,士民皆衣纸”。十一月,史朝义自濮州北渡黄河。唐军追至昌乐,又打败史朝义。
于是,叛军邺郡节度使薛嵩以相、卫、洺、邢四州降唐,恒阳节度使张忠志以赵、恒、深、定、易五州降唐。代宗赐张忠志姓李,名宝臣,并命其为成德节度使,仍统原来五州之地。
广德元年(763)正月,史朝义败走莫州(治所在今河北雄县南),其部将田承嗣赶走史朝义,自己降唐。史朝义又走范阳,其范阳节度使李怀仙也已降唐。
史朝义部众看到大势已去,都纷纷离去。最后,史朝义带数百胡骑欲北去奚或契丹,李怀仙又穷追不舍,史朝义走投无路,自缢于林中。
至此,历时八年的安史之乱才被平定。