第一阶段:217年冬到218年底 刘备接受法正的建议,集中主力争夺汉中。其部署为: 刘备率法正、黄忠、魏延、赵云、高详、刘封等将进攻夏侯渊军据守的进入汉中之要隘阳平关,以期夺占阳平关将曹军驱除出汉中地区; 张飞、马超、吴兰、雷铜、任夔等将进攻武都郡(下辩一带),既可切断曹军从陇右地区向汉中增援兵力和粮草的通道,又保证刘备主力的侧翼安全; 曹军以夏侯渊军主力据守阳平关,张郃军守广石,确保汉中门户的安全;以曹洪、曹真军抵抗张飞的部队,确保阳平关侧翼和西路粮道的安全;以徐晃军机动防御马鸣阁至阳平一带,保障阳平关侧后之安全。
217年冬,刘备军开始自成都向汉中进兵,张飞部进军下辩。 218年春,张飞部到达下辩,与曹洪军相持。张飞分兵,扬言要出击曹洪军的后路,被曹真等人识破,结果前军吴兰等部被曹洪军集中兵力击破,雷铜、任夔战死,吴兰逃到少数民族部落后被杀。张飞看到损失较大,有利地形已经被曹军占领,估计无法再发动进攻,就撤出了武都地区。张飞军总共约2万人,此次作战估计损失5千以上,大将3员。 同期,刘备的主力与夏侯渊、张郃军一直相持在阳平关一带,刘备屡攻不下,损失也不小。
218年7月,刘备派陈式军攻击马鸣阁道,希望切断阳平北面道路,从侧后方威胁阳平。结果遭到徐晃军的打击,损失惨重,许多士兵因山路狭窄而落入山涧。 这时,刘备的夺取汉中之计划遇到了极大的困难,主力仰攻阳平不下,侧翼迂回的两路部队均遭到失败,曹军已经威胁到其主力的侧翼安全了,而且兵力也损失很大(前后相加估计1~1。5万左右)。只好紧急征调成都的留守部队到汉中前线。
第二阶段:219年1月 诸葛亮及时将成都的部队集中后全部派往汉中,缓解了刘备的危急形势。 219年1月,刘备放弃进攻阳平,渡过汉水,向定军山一带机动,希望以此调动夏侯渊军离开坚固阵地,在运动中寻找战机。夏侯渊果然中计,与张郃率军也渡过汉水,在定军山扎下大营。
刘备采用声东击西战术,先猛攻张郃军防守的东面,夏侯渊惟恐张郃兵少抵挡不住,就分兵一半增援。接着刘备火烧夏侯渊防守的西面外围,趁夏侯渊出营救火,放松警戒的时机,突然派黄忠从山上发起突击,一举斩杀夏侯渊,并击败其残余部队,益州刺史赵颙也同时阵亡。 张郃军守不住定军山大营,只好退过汉水扎营,并收拢散兵。夏侯渊的司马郭淮等临时推举张郃统一指挥剩余的部队。 刘备军准备渡过汉水继续攻击张郃军。张郃准备沿河阻击。
这时郭淮建议:沿河阻击是示弱的表现,应把部队向后移动,让刘备军渡河,待其半渡而击之。张郃采纳了这个建议。刘备看到曹军的部署担心渡河有危险,于是放弃了渡河追击的企图。张郃于是率军退回阳平继续坚守。 曹操得到夏侯渊阵亡,曹军损失很大,情况危急的消息后,命令曹真火速增援阳平。曹真到达后,指挥徐晃军反击刘备派出的高详军,获得胜利,暂时稳定了战场形势。
第三阶段:219年2月~5月 219年2月,得到夏侯渊战败的消息,曹操急忙从长安赶到阳平一带,准备与刘备的主力展开决战。曹操是在218年7月开始自邺出发的,于当年9月到达长安。由于10月发生了宛城守将侯音叛变事件,加之当时汉中局势比较平稳,曹操于是留在长安观察局势发展,再决定进一步的行动(比如可能要增援宛城的平叛作战)。
由于219年1月夏侯渊的阵亡,曹操马上率军进入汉中。 219年3~5月,刘备依靠大巴山的险要地形,坚守不出,曹操进攻又没有效果,而曹军的运输线因过于漫长,还经常遭到刘备军的偷袭,后勤得不到保障,最后曹操决定将所有部队撤离汉中。 同时(或在此前)撤出的还有汉中的人民8万多人和武都郡的少数民族5万余户。 汉中战役到此全部结束。