Q:

Why and how does volatile imply atomic reads/writes? 

First off, I'm aware that volatile does not make multiple operations (as i++) atomic.  This question is about a single read or write operation. 
My initial understanding was that volatile only enforces a memory barrier (i.e. other threads will be able to see updated values). 
Now I've noticed that JLS section 17.7 says that volatile additionally makes a single read or write atomic.  For instance, given two threads, both writing a different value to a volatile long x, then x will finally represent exactly one of the values. 
I'm curious how this is possible.  On a 32 bit system, if two threads write to a 64 bit location in parallel and without "proper" synchronization (i.e. some kind of lock), it should be possible for the result to be a mixup.  For clarity, let's use an example in which thread 1 writes 0L while thread 2 writes -1L to the same 64 bit memory location. 
T1 writes lower 32 bit
T2 writes lower 32 bit
T2 writes upper 32 bit
T1 writes upper 32 bit

The result could then be 0x0000FFFF, which is undesirable.  How does volatile prevent this scenario? 
I've also read elsewhere that this does, typically, not degrade performance.  How is it possible to synchronize writes with only a minor speed impact? 

A:

Your statement that volatile only enforces a memory barrier (in the meaning, flushes the processor cache) is false.  It also implies a happens-before relationship of read-write combinations of volatile values.  For example:
class Foo {
  volatile boolean x;
  boolean y;

  void qux() {
    x = true; // volatile write
    y = true;
  }

  void baz() {
    System.out.print(x); // volatile read
    System.out.print(" ");
    System.out.print(y);
  }
}

When you run both methods from two threads, the above code will either print true false, true true or false false but never false true.  Without the volatile keyword, you are not guaranteed the later condition because the JIT compiler might reorder statements.  
The same way as the JIT compiler can assure this condition, is can guard 64-bit value reads and writes in the assembly.  volatile values are treated explicitly by the JIT compiler to assure their atomicity.  Some processor instruction sets support this directly by specific 64-bit instructions, otherwise the JIT compiler emulates it. 
The JVM is more complex as you might expect it to be and it is often explained without full scope.  Consider reading this excellent article which covers all the details.