f = Module[{tmp = ConstantArray[0, Dimensions[#1] + {0, 0, 1}]}, 
 tmp[[All, All, ;; -2]] = #1; tmp[[All, All, -1]] = #2; tmp] &;
 f[a, b]
 (* {{{1, 2, 0}, {3, 4, 0}},
 {{5, 6, 1}, {7, 8, 1}}, 
 {{9, 10, 2}, {11, 12, 2}}}*)

All methods posted so far:

 f1 = MapThread[Append, {#1, #2}, 2] &;
 f2 = Join[#1, Transpose[{#2}, {3, 1, 2}], 3] &;
 f3 = MapThread[{Sequence @@ #1, #2} &, {#1, #2}, 2] &;
 f4 = MapThread[Flatten[{##}] &, {#1, #2}, 2] &;
 f5 = MapThread[Insert[#1, #2, -1] &, {#1, #2}, 2] &;
 f6 = MapThread[Join[#1, {#2}] &, {#1, #2}, 2] &;
 f7 = Partition[MapThread[Append, {Flatten[#1, 1], #2 // Flatten}], 2] &;
 f8 = Join[#1, Map[List, #2, {-1}], 3] &;
 f9 = Module[{tmp = ConstantArray[0, Dimensions[#1] + {0, 0, 1}]}, 
 tmp[[All, All, ;; -2]] = #1; tmp[[All, All, -1]] = #2; tmp] &;


`Timing`s and `ByteCount`s using Mr.W's test setup:

 A = RandomInteger[99, {700, 400, 200}];
 B = RandomInteger[99, {700, 400}];
 Grid[{#[[1]], #[[2, 1]], #[[2, 2]]} & /@
 ({#, #[A, B] // ByteCount // Timing} & /@ {f1, f2, f3, f4, f5, f6, f7, f8, f9}), 
 Dividers -> All] // Style[#, 16] &

![enter image description here][1]


 [1]: https://i.sstatic.net/4wAJ1.png