diff --git a/dune/grid/common/mcmgmapper.hh b/dune/grid/common/mcmgmapper.hh
index db2976e1c968809df8760b63776be6a3dce10cc2..97a57f8c0271f9dd6b25d4040e87cb03a0406e64 100644
--- a/dune/grid/common/mcmgmapper.hh
+++ b/dune/grid/common/mcmgmapper.hh
@@ -159,7 +159,11 @@ namespace Dune
      */
     Index subIndex (const typename GV::template Codim<0>::Entity& e, int i, unsigned int codim) const
     {
-      GeometryType gt=ReferenceElements<double,GV::dimension>::general(e.type()).type(i,codim);
+      const GeometryType eType = e.type();
+      GeometryType gt = eType.isNone() ?
+        GeometryType( GeometryType::none, GV::dimension - codim ) :
+        ReferenceElements<double,GV::dimension>::general(eType).type(i,codim) ;
+      //GeometryType gt=ReferenceElements<double,GV::dimension>::general(e.type()).type(i,codim);
       assert(layout.contains(gt));
       return is.subIndex(e, i, codim) + offset[GlobalGeometryTypeIndex::index(gt)];
     }
@@ -205,7 +209,11 @@ namespace Dune
      */
     bool contains (const typename GV::template Codim<0>::Entity& e, int i, int cc, Index& result) const
     {
-      GeometryType gt=ReferenceElements<double,GV::dimension>::general(e.type()).type(i,cc);
+      const GeometryType eType = e.type();
+      const GeometryType gt = eType.isNone() ?
+        GeometryType( GeometryType::none, GV::dimension - cc ) :
+        ReferenceElements<double,GV::dimension>::general(eType).type(i,cc) ;
+      //GeometryType gt=ReferenceElements<double,GV::dimension>::general(e.type()).type(i,cc);
       if (not layout.contains(gt))
         return false;
       result = is.subIndex(e, i, cc) + offset[GlobalGeometryTypeIndex::index(gt)];
diff --git a/dune/grid/io/file/vtk/common.hh b/dune/grid/io/file/vtk/common.hh
index a184eea8bc47012530516080e488c6debf47b43e..9898095e037b7fb6f37f43756f9017211e81562d 100644
--- a/dune/grid/io/file/vtk/common.hh
+++ b/dune/grid/io/file/vtk/common.hh
@@ -184,7 +184,8 @@ namespace Dune
       tetrahedron = 10,
       hexahedron = 12,
       prism = 13,
-      pyramid = 14 //, polyhedron = 42
+      pyramid = 14,
+      polyhedron = 42
     };
 
     //! mapping from GeometryType to VTKGeometryType
@@ -207,7 +208,7 @@ namespace Dune
       if (t.isNone() )
       {
         if( t.dim() == 2 ) return polygon;
-        // if( t.dim() == 3 ) return polyhedron;
+        if( t.dim() == 3 ) return polyhedron;
       }
 
       DUNE_THROW(IOError,"VTKWriter: unsupported GeometryType " << t);
diff --git a/dune/grid/io/file/vtk/vtkwriter.hh b/dune/grid/io/file/vtk/vtkwriter.hh
index 75e950e2a4c50c9c770f964c74c0ae795aec49ed..5d75a8607fbc100750a9268f0f5bb64c662f518f 100644
--- a/dune/grid/io/file/vtk/vtkwriter.hh
+++ b/dune/grid/io/file/vtk/vtkwriter.hh
@@ -14,6 +14,7 @@
 
 #include <vector>
 #include <list>
+#include <map>
 
 #include <dune/common/typetraits.hh>
 #include <dune/common/exceptions.hh>
@@ -576,7 +577,8 @@ namespace Dune
     explicit VTKWriter ( const GridView &gridView,
                          VTK::DataMode dm = VTK::conforming )
       : gridView_( gridView ),
-        datamode( dm )
+        datamode( dm ),
+        polyhedralCellsPresent_( checkForPolyhedralCells() )
     { }
 
     /**
@@ -1262,19 +1264,173 @@ namespace Dune
       // types
       if (n>1)
       {
-        std::shared_ptr<VTK::DataArrayWriter<unsigned char> > p3
-          (writer.makeArrayWriter<unsigned char>("types", 1, ncells));
-        if(!p3->writeIsNoop())
-          for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
+        {
+          std::shared_ptr<VTK::DataArrayWriter<unsigned char> > p3
+            (writer.makeArrayWriter<unsigned char>("types", 1, ncells));
+
+          if(!p3->writeIsNoop())
           {
-            int vtktype = VTK::geometryType(it->type());
-            p3->write(vtktype);
+            for (CellIterator it=cellBegin(); it!=cellEnd(); ++it)
+            {
+              int vtktype = VTK::geometryType(it->type());
+              p3->write(vtktype);
+            }
           }
+        }
+
+
+        // if polyhedron cells found also cell faces need to be written
+        if( polyhedralCellsPresent_ )
+        {
+          writeCellFaces( writer );
+        }
       }
 
       writer.endCells();
     }
 
+  protected:
+    bool checkForPolyhedralCells() const
+    {
+      // check if polyhedron cells are present
+      for( const auto& geomType : gridView_.indexSet().types( 0 ) )
+      {
+        if( VTK::geometryType( geomType ) == VTK::polyhedron )
+        {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    //! write the connectivity array
+    virtual void writeCellFaces(VTK::VTUWriter& writer)
+    {
+      if( ! faceVertices_ )
+      {
+        faceVertices_.reset( new std::pair< std::vector<int>, std::vector<int> > () );
+        // fill face vertex structure
+        fillFaceVertices( cornerBegin(), cornerEnd(), gridView_.indexSet(),
+                          faceVertices_->first, faceVertices_->second );
+      }
+
+      std::vector< int >& faces = faceVertices_->first;
+      std::vector< int >& faceOffsets = faceVertices_->second;
+      assert( int(faceOffsets.size()) == ncells );
+
+      {
+        std::shared_ptr<VTK::DataArrayWriter< int > > p4
+          (writer.makeArrayWriter< int >("faces", 1, faces.size()));
+        if(!p4->writeIsNoop())
+        {
+          for( const auto& face : faces )
+            p4->write( face );
+        }
+      }
+
+      {
+        std::shared_ptr<VTK::DataArrayWriter< int > > p5
+          (writer.makeArrayWriter< int >("faceoffsets", 1, ncells ));
+        if(!p5->writeIsNoop())
+        {
+          for( const auto& offset : faceOffsets )
+            p5->write( offset );
+
+          // clear face vertex structure
+          faceVertices_.reset();
+        }
+      }
+    }
+
+    template <class CornerIterator, class IndexSet, class T>
+    inline void fillFaceVertices( CornerIterator it,
+                           const CornerIterator end,
+                           const IndexSet& indexSet,
+                           std::vector<T>& faces,
+                           std::vector<T>& faceOffsets )
+    {
+      if( n == 3 && it != end )
+      {
+        // clear output arrays
+        faces.clear();
+        faces.reserve( 15 * ncells );
+        faceOffsets.clear();
+        faceOffsets.reserve( ncells );
+
+        int offset = 0;
+
+        Cell element = *it;
+        int elIndex = indexSet.index( element );
+        std::vector< T > vertices;
+        vertices.reserve( 30 );
+        for( ; it != end; ++it )
+        {
+          const Cell& cell = *it ;
+          const int cellIndex = indexSet.index( cell ) ;
+          if( elIndex != cellIndex )
+          {
+            fillFacesForElement( element, indexSet, vertices, offset, faces, faceOffsets );
+
+            vertices.clear();
+            element = cell ;
+            elIndex = cellIndex ;
+          }
+          vertices.push_back( it.id() );
+        }
+
+        // fill faces for last element
+        fillFacesForElement( element, indexSet, vertices, offset, faces, faceOffsets );
+      }
+    }
+
+    template <class Entity, class IndexSet, class T>
+    static void fillFacesForElement( const Entity& element,
+                                     const IndexSet& indexSet,
+                                     const std::vector<T>& vertices,
+                                     T& offset,
+                                     std::vector<T>& faces,
+                                     std::vector<T>& faceOffsets )
+    {
+      const int dim = n;
+
+      std::map< T, T > vxMap;
+
+      // get number of local faces
+      const int nVertices = element.subEntities( dim );
+      for( int vx = 0; vx < nVertices; ++ vx )
+      {
+        const int vxIdx = indexSet.subIndex( element, vx, dim );
+        vxMap[ vxIdx ] = vertices[ vx ];
+      }
+
+      // get number of local faces
+      const int nFaces = element.subEntities( 1 );
+      // store number of faces for current element
+      faces.push_back( nFaces );
+      ++offset;
+      // extract each face as a set of vertex indices
+      for( int fce = 0; fce < nFaces; ++ fce )
+      {
+        // obtain face
+        const auto face = element.template subEntity< 1 > ( fce );
+
+        // get all vertex indices from current face
+        const int nVxFace = face.subEntities( dim );
+        faces.push_back( nVxFace );
+        ++offset ;
+        for( int i=0; i<nVxFace; ++i )
+        {
+          const T vxIndex = indexSet.subIndex( face, i, dim );
+          assert( vxMap.find( vxIndex ) != vxMap.end() );
+          faces.push_back( vxMap[ vxIndex ] );
+          ++offset ;
+        }
+      }
+
+      // store face offset for each element
+      faceOffsets.push_back( offset );
+    }
+
   protected:
     // the list of registered functions
     std::list<VTKLocalFunction> celldata;
@@ -1293,6 +1449,13 @@ namespace Dune
     // hold its number in the iteration order (VertexIterator)
     std::vector<int> number;
     VTK::DataMode datamode;
+
+    // true if polyhedral cells are present in the grid
+    const bool polyhedralCellsPresent_;
+
+    // pointer holding face vertex connectivity if needed
+    std::shared_ptr< std::pair< std::vector<int>, std::vector<int> > > faceVertices_;
+
   protected:
     VTK::OutputType outputtype;
   };