diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
index 7df85dc6d55f4c798ed9f86d6ba9eb1a899687c1..3b3ad474b77ba1eb0fab86781d7c99418ce8cba0 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
@@ -27,6 +27,7 @@ License
 #include "entry.H"
 #include "demandDrivenData.H"
 #include "stringListOps.H"
+#include "Pstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -372,6 +373,84 @@ bool Foam::ZoneMesh<ZoneType, MeshType>::checkDefinition
 }
 
 
+template<class ZoneType, class MeshType>
+bool Foam::ZoneMesh<ZoneType, MeshType>::checkParallelSync
+(
+    const bool report
+) const
+{
+    if (!Pstream::parRun())
+    {
+        return false;
+    }
+
+
+    const PtrList<ZoneType>& zones = *this;
+
+    bool hasError = false;
+
+    // Collect all names
+    List<wordList> allNames(Pstream::nProcs());
+    allNames[Pstream::myProcNo()] = this->names();
+    Pstream::gatherList(allNames);
+    Pstream::scatterList(allNames);
+
+    List<wordList> allTypes(Pstream::nProcs());
+    allTypes[Pstream::myProcNo()] = this->types();
+    Pstream::gatherList(allTypes);
+    Pstream::scatterList(allTypes);
+
+    // Have every processor check but only master print error.
+
+    for (label procI = 1; procI < allNames.size(); procI++)
+    {
+        if
+        (
+            (allNames[procI] != allNames[0])
+         || (allTypes[procI] != allTypes[0])
+        )
+        {
+            hasError = true;
+
+            if (debug || (report && Pstream::master()))
+            {
+                Info<< " ***Inconsistent zones across processors, "
+                       "processor 0 has zone names:" << allNames[0]
+                    << " zone types:" << allTypes[0]
+                    << " processor " << procI << " has zone names:"
+                    << allNames[procI]
+                    << " zone types:" << allTypes[procI]
+                    << endl;
+            }
+        }
+    }
+
+    // Check contents
+    if (!hasError)
+    {
+        forAll(zones, zoneI)
+        {
+            if (zones[zoneI].checkParallelSync(false))
+            {
+                hasError = true;
+
+                if (debug || (report && Pstream::master()))
+                {
+                    Info<< " ***Zone " << zones[zoneI].name()
+                        << " of type " << zones[zoneI].type()
+                        << " is not correctly synchronised"
+                        << " across coupled boundaries."
+                        << " (coupled faces are either not both "
+                        << " present in set or have same flipmap)" << endl;
+                }
+            }
+        }
+    }
+
+    return hasError;
+}
+
+
 // Correct zone mesh after moving points
 template<class ZoneType, class MeshType>
 void Foam::ZoneMesh<ZoneType, MeshType>::movePoints(const pointField& p)
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
index 8854d9533b0e4aed4cb67357fc01d3010c98e191..15f715df5c8bc7a91f54cc44c602e5447d140b7d 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
@@ -149,6 +149,10 @@ public:
         //- Check zone definition. Return true if in error.
         bool checkDefinition(const bool report = false) const;
 
+        //- Check whether all procs have all zones and in same order. Return
+        //  true if in error.
+        bool checkParallelSync(const bool report = false) const;
+
         //- Correct zone mesh after moving points
         void movePoints(const pointField&);
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
index 5f5d60a30fc87118a25b5a289b88886e11f24163..54b5ba9eb01debfa9c50fade5a3043ebf0066dce 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
@@ -209,6 +209,13 @@ public:
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
 
+        //- Check whether zone is synchronised across coupled boundaries. Return
+        //  true if in error.
+        virtual bool checkParallelSync(const bool report = false) const
+        {
+            return false;
+        }
+
         //- Write dictionary
         virtual void writeDict(Ostream&) const;
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
index d6bca05438f60c62d1badae78098d2a1c9de820e..a37a786ae2b9c52f85e6460c8e7cfea440e170b0 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
@@ -29,6 +29,7 @@ License
 #include "polyMesh.H"
 #include "primitiveMesh.H"
 #include "demandDrivenData.H"
+#include "syncTools.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -134,6 +135,49 @@ bool Foam::pointZone::checkDefinition(const bool report) const
 }
 
 
+bool Foam::pointZone::checkParallelSync(const bool report) const
+{
+    const polyMesh& mesh = zoneMesh().mesh();
+
+    labelList maxZone(mesh.nPoints(), -1);
+    labelList minZone(mesh.nPoints(), labelMax);
+    forAll(*this, i)
+    {
+        label pointI = operator[](i);
+        maxZone[pointI] = index();
+        minZone[pointI] = index();
+    }
+    syncTools::syncPointList(mesh, maxZone, maxEqOp<label>(), -1);
+    syncTools::syncPointList(mesh, minZone, minEqOp<label>(), labelMax);
+
+    bool error = false;
+
+    forAll(maxZone, pointI)
+    {
+        // Check point in zone on both sides
+        if (maxZone[pointI] != minZone[pointI])
+        {
+            if (report && !error)
+            {
+                Info<< " ***Problem with pointZone " << index()
+                    << " named " << name()
+                    << ". Point " << pointI
+                    << " at " << mesh.points()[pointI]
+                    << " is in zone "
+                    << (minZone[pointI] == labelMax ? -1 : minZone[pointI])
+                    << " on some processors and in zone "
+                    << maxZone[pointI]
+                    << " on some other processors."
+                    << endl;
+            }
+            error = true;
+        }
+    }
+
+    return error;
+}
+
+
 void Foam::pointZone::writeDict(Ostream& os) const
 {
     os  << nl << name_ << nl << token::BEGIN_BLOCK << nl
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
index 177953990cfea7a2fdaf4afb0edc9ce230eefb88..22079a9407cf46706fc59a36640c1e5a7e6d5c9c 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
@@ -208,6 +208,10 @@ public:
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
 
+        //- Check whether zone is synchronised across coupled boundaries. Return
+        //  true if in error.
+        virtual bool checkParallelSync(const bool report = false) const;
+
         //- Correct patch after moving points
         virtual void movePoints(const pointField&)
         {}