The memoryBarrier() suite of functions controls the ordering of writes from shaders. The barrier() function, usable only from tessellation control/compute shaders, effectively halts the invocation until all other shaders in the same patch/work group have reached that barrier.

Both tessellation control and compute shaders have ways to communicate through local memory (patch and shared variables, respectively). The effects of the barrier() function should also ensure that all of the appropriate invocations have written to any non-local memory via images and such. Thus, if you run out of local memory, you could use an image as some workspace for these shaders.

What is unclear to me is this: do you still need the memoryBarrier() call to ensure ordering, even though you know that all of the shader invocations of interest executed up to that point already? I think you do, but I'm still trying to parse the spec on this stuff.