diff --git a/dumux/common/properties.hh b/dumux/common/properties.hh
index aee63d335e022d3bfee25089bbc6b30891132c7c..6fb5a53ff6429d3c00264ba2d283060a080720a2 100644
--- a/dumux/common/properties.hh
+++ b/dumux/common/properties.hh
@@ -124,6 +124,9 @@ NEW_PROP_TAG(UseKelvinEquation);                   //!< If we use Kelvin equatio
 // or at the scvf center for analytical permeability fields (e.g. convergence studies)
 NEW_PROP_TAG(EvaluatePermeabilityAtScvfIP);
 
+// When using the box method in a multi-phase context, an interface solver might be necessary
+NEW_PROP_TAG(EnableBoxInterfaceSolver);
+
 //////////////////////////////////////////////////////////////
 // Additional properties used by the 2pnc and 2pncmin models:
 //////////////////////////////////////////////////////////////
diff --git a/dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh b/dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh
new file mode 100644
index 0000000000000000000000000000000000000000..4c50018aedbfbbe71b542a746a11d66dd1b75065
--- /dev/null
+++ b/dumux/porousmediumflow/2p/boxmaterialinterfaceparams.hh
@@ -0,0 +1,116 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup TwoPModel
+ * \brief copydoc Dumux::TwoPScvSaturationReconstruction
+ */
+#ifndef DUMUX_2P_BOX_MATERIAL_INTERFACE_PARAMS_HH
+#define DUMUX_2P_BOX_MATERIAL_INTERFACE_PARAMS_HH
+
+#include <dune/common/exceptions.hh>
+
+#include <dumux/discretization/methods.hh>
+#include <dumux/discretization/box/elementsolution.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup TwoPModel
+ * \brief Class that determines the material with the lowest capillary
+ *        pressure (under fully water-saturated conditions) around the nodes
+ *        of a grid. These parameters are then associated with the global degree
+ *        of freedom. On the basis of these parameters, the saturations in the
+ *        remaining sub-control volumes connected to the vertex can be reconstructed.
+ */
+template<class SpatialParams>
+class BoxMaterialInterfaceParams
+{
+public:
+    using MaterialLawParams = typename SpatialParams::MaterialLaw::Params;
+
+    /*!
+     * \brief Update the scv -> dofparameter map
+     *
+     * \param The finite volume grid geometry
+     * \param SpatialParams Class encapsulating the spatial parameters
+     * \param x The current state of the solution vector
+     */
+    template<class FVGridGeometry, class SolutionVector>
+    void update(const FVGridGeometry& fvGridGeometry,
+                const SpatialParams& spatialParams,
+                const SolutionVector& x)
+    {
+        using MaterialLaw = typename SpatialParams::MaterialLaw;
+
+        // Make sure the spatial params return a const ref and no copy!
+        using Elem = typename FVGridGeometry::GridView::template Codim<0>::Entity;
+        using ElemSol = decltype( elementSolution(Elem(), x, fvGridGeometry) );
+        using Scv = typename FVGridGeometry::SubControlVolume;
+        using ReturnType = decltype(spatialParams.materialLawParams(Elem(), Scv(), ElemSol()));
+        static_assert(std::is_same<ReturnType, const MaterialLawParams&>::value,
+                      "In order to use the box-interface solver please provide access "
+                      "to the material law parameters via returning (const) references");
+
+        // make sure this is only called for geometries of the box method!
+        if (FVGridGeometry::discMethod != DiscretizationMethod::box)
+            DUNE_THROW(Dune::InvalidStateException, "Determination of the interface material parameters with "
+                                                    "this class only makes sense when using the box method!");
+
+        isOnMaterialInterface_.resize(fvGridGeometry.numDofs(), true);
+        dofParams_.resize(fvGridGeometry.numDofs(), nullptr);
+        for (const auto& element : elements(fvGridGeometry.gridView()))
+        {
+            const auto elemSol = elementSolution(element, x, fvGridGeometry);
+
+            auto fvGeometry = localView(fvGridGeometry);
+            fvGeometry.bind(element);
+            for (const auto& scv : scvs(fvGeometry))
+            {
+                const auto& params = spatialParams.materialLawParams(element, scv, elemSol);
+
+                // is no parameters had been set, set them now
+                if (dofParams_[scv.dofIndex()] == nullptr)
+                    dofParams_[scv.dofIndex()] = &params;
+
+                // otherwise only use the current ones if endPointPc (e.g. Brooks-Corey entry pressure) is lower
+                else if (MaterialLaw::endPointPc( params ) < MaterialLaw::endPointPc( *(dofParams_[scv.dofIndex()]) ))
+                    dofParams_[scv.dofIndex()] = &params;
+            }
+        }
+    }
+
+    //! Return if this scv is connected to a material interface
+    template<class Scv>
+    bool isOnMaterialInterface(const Scv& scv) const
+    { return isOnMaterialInterface_[scv.dofIndex()]; }
+
+    //! Return the material parameters associated with the dof
+    template<class Scv>
+    const MaterialLawParams& getDofParams(const Scv& scv) const
+    { return *(dofParams_[scv.dofIndex()]); }
+
+private:
+    std::vector<bool> isOnMaterialInterface_;
+    std::vector<const MaterialLawParams*> dofParams_;
+};
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p/model.hh b/dumux/porousmediumflow/2p/model.hh
index 1aacdb680e02b1c7f0269bbb7d5ca5e21d2d9426..c6bfff71e0dd89cac8b6e911c2b1b72ea93c30e7 100644
--- a/dumux/porousmediumflow/2p/model.hh
+++ b/dumux/porousmediumflow/2p/model.hh
@@ -75,6 +75,7 @@
 #include "indices.hh"
 #include "volumevariables.hh"
 #include "vtkoutputfields.hh"
+#include "saturationreconstruction.hh"
 
 namespace Dumux
 {
@@ -108,8 +109,10 @@ struct TwoPModelTraits
  * \tparam FST The fluid state type
  * \tparam PT The type used for permeabilities
  * \tparam MT The model traits
+ * \tparam SR The class used for reconstruction of
+ *            non-wetting phase saturations in scvs
  */
-template<class PV, class FSY, class FST, class PT, class MT>
+template<class PV, class FSY, class FST, class PT, class MT, class SR>
 struct TwoPVolumeVariablesTraits
 {
     using PrimaryVariables = PV;
@@ -117,6 +120,7 @@ struct TwoPVolumeVariablesTraits
     using FluidState = FST;
     using PermeabilityType = PT;
     using ModelTraits = MT;
+    using SaturationReconstruction = SR;
 };
 
 ////////////////////////////////
@@ -160,7 +164,12 @@ private:
     using MT = typename GET_PROP_TYPE(TypeTag, ModelTraits);
     using PT = typename GET_PROP_TYPE(TypeTag, SpatialParams)::PermeabilityType;
 
-    using Traits = TwoPVolumeVariablesTraits<PV, FSY, FST, PT, MT>;
+    static constexpr auto DM = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod;
+    static constexpr bool enableIS = GET_PROP_VALUE(TypeTag, EnableBoxInterfaceSolver);
+    // class used for scv-wise reconstruction of non-wetting phase saturations
+    using SR = TwoPScvSaturationReconstruction<DM, enableIS>;
+
+    using Traits = TwoPVolumeVariablesTraits<PV, FSY, FST, PT, MT, SR>;
 public:
     using type = TwoPVolumeVariables<Traits>;
 };
diff --git a/dumux/porousmediumflow/2p/saturationreconstruction.hh b/dumux/porousmediumflow/2p/saturationreconstruction.hh
new file mode 100644
index 0000000000000000000000000000000000000000..54ddf4bec5f019fd1e4f6e8d13e8cee3e9efd6a9
--- /dev/null
+++ b/dumux/porousmediumflow/2p/saturationreconstruction.hh
@@ -0,0 +1,105 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup TwoPModel
+ * \brief copydoc Dumux::TwoPScvSaturationReconstruction
+ */
+#ifndef DUMUX_2P_SCV_SATURATION_RECONSTRUCTION_HH
+#define DUMUX_2P_SCV_SATURATION_RECONSTRUCTION_HH
+
+#include <dumux/discretization/methods.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup TwoPModel
+ * \brief Class that computes the non-wetting saturation in an scv from the saturation
+ *        at the global degree of freedom. This is only necessary in conjunction with
+ *        the box scheme where the degrees of freedom lie on material interfaces. There
+ *        the non-wetting phase saturation is generally discontinuous.
+ */
+template<DiscretizationMethod M, bool enableReconstruction>
+class TwoPScvSaturationReconstruction
+{
+public:
+    /*!
+     * \brief Compute the non-wetting phase saturation.
+     * \note In the general case, we don't do anything. We do
+     *       stuff only in the specialization for the box scheme below.
+     *
+     * \param SpatialParams Class encapsulating the spatial parameters
+     * \param element The finite element the scv is embedded in
+     * \param scv The sub-control volume for which the saturation is computed
+     * \param elemSol The solution at all dofs inside this element
+     * \param Sn The non-wetting phase saturation at the global dof
+     */
+    template<class SpatialParams, class Element, class Scv, class ElemSol>
+    static typename ElemSol::PrimaryVariables::value_type
+    reconstructSn(const SpatialParams& spatialParams,
+                  const Element& element,
+                  const Scv& scv,
+                  const ElemSol& elemSol,
+                  typename ElemSol::PrimaryVariables::value_type Sn)
+    { return Sn; }
+};
+
+//! Specialization for the box scheme with the interface solver enabled
+template<>
+class TwoPScvSaturationReconstruction<DiscretizationMethod::box, /*enableReconstruction*/true>
+{
+public:
+    /*!
+     * \brief Compute
+     *
+     * \param SpatialParams Class encapsulating the spatial parameters
+     * \param element The finite element the scv is embedded in
+     * \param scv The sub-control volume for which the saturation is computed
+     * \param elemSol The solution at all dofs inside this element
+     * \param Sn The non-wetting phase saturation at the global dof
+     */
+    template<class SpatialParams, class Element, class Scv, class ElemSol>
+    static typename ElemSol::PrimaryVariables::value_type
+    reconstructSn(const SpatialParams& spatialParams,
+                  const Element& element,
+                  const Scv& scv,
+                  const ElemSol& elemSol,
+                  typename ElemSol::PrimaryVariables::value_type Sn)
+    {
+        // if this dof doesn't lie on a material interface, simply return Sn
+        if (!spatialParams.materialInterfaceParams().isOnMaterialInterface(scv))
+            return Sn;
+
+        using MaterialLaw = typename SpatialParams::MaterialLaw;
+        // compute capillary pressure using material parameters associated with the dof
+        const auto& ifMaterialParams = spatialParams.materialInterfaceParams().getDofParams(scv);
+        const auto pc = MaterialLaw::pc(ifMaterialParams, /*Sw=*/1.0 - Sn);
+
+        // reconstruct by inverting the pc-sw curve
+        const auto& materialLawParams = spatialParams.materialLawParams(element, scv, elemSol);
+        const auto pcMin = MaterialLaw::endPointPc(materialLawParams);
+
+        if (pc < pcMin && pcMin > 0.0) return 0.0;
+        else return 1.0 - MaterialLaw::sw(materialLawParams, pc);
+    }
+};
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p/volumevariables.hh b/dumux/porousmediumflow/2p/volumevariables.hh
index 2675a44511882cf48f51703e0dfd3ca6cb60987c..f24e5fdaa94250364b93e70bc8fdda50d2272763 100644
--- a/dumux/porousmediumflow/2p/volumevariables.hh
+++ b/dumux/porousmediumflow/2p/volumevariables.hh
@@ -44,7 +44,6 @@ class TwoPVolumeVariables
     using PermeabilityType = typename Traits::PermeabilityType;
     using ModelTraits = typename Traits::ModelTraits;
     using Indices = typename ModelTraits::Indices;
-    static constexpr auto formulation = ModelTraits::priVarFormulation();
     using Scalar = typename Traits::PrimaryVariables::value_type;
     using FS = typename Traits::FluidSystem;
 
@@ -57,6 +56,7 @@ class TwoPVolumeVariables
         phase1Idx = FS::phase1Idx
     };
 
+    static constexpr auto formulation = ModelTraits::priVarFormulation();
 
 public:
     //! export type of fluid system
@@ -130,28 +130,44 @@ public:
 
         const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol);
         if (formulation == TwoPFormulation::p0s1)
-        {
-            fluidState.setSaturation(phase1Idx, priVars[saturationIdx]);
-            fluidState.setSaturation(phase0Idx, 1 - priVars[saturationIdx]);
-        }
-        else if (formulation == TwoPFormulation::p1s0)
-        {
-            fluidState.setSaturation(phase0Idx, priVars[saturationIdx]);
-            fluidState.setSaturation(phase1Idx, 1 - priVars[saturationIdx]);
-        }
-
-        pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
-        if (formulation == TwoPFormulation::p0s1)
         {
             fluidState.setPressure(phase0Idx, priVars[pressureIdx]);
-            fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_
-                                                                       : priVars[pressureIdx] - pc_);
+            if (wPhaseIdx == phase1Idx)
+            {
+                fluidState.setSaturation(phase1Idx, priVars[saturationIdx]);
+                fluidState.setSaturation(phase0Idx, 1 - priVars[saturationIdx]);
+                pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
+                fluidState.setPressure(phase1Idx, priVars[pressureIdx] - pc_);
+            }
+            else
+            {
+                const auto Sn = Traits::SaturationReconstruction::reconstructSn(problem.spatialParams(), element,
+                                                                                scv, elemSol, priVars[saturationIdx]);
+                fluidState.setSaturation(phase1Idx, Sn);
+                fluidState.setSaturation(phase0Idx, 1 - Sn);
+                pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
+                fluidState.setPressure(phase1Idx, priVars[pressureIdx] + pc_);
+            }
         }
         else if (formulation == TwoPFormulation::p1s0)
         {
             fluidState.setPressure(phase1Idx, priVars[pressureIdx]);
-            fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_
-                                                                       : priVars[pressureIdx] + pc_);
+            if (wPhaseIdx == phase1Idx)
+            {
+                const auto Sn = Traits::SaturationReconstruction::reconstructSn(problem.spatialParams(), element,
+                                                                                scv, elemSol, priVars[saturationIdx]);
+                fluidState.setSaturation(phase0Idx, Sn);
+                fluidState.setSaturation(phase1Idx, 1 - Sn);
+                pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
+                fluidState.setPressure(phase0Idx, priVars[pressureIdx] + pc_);
+            }
+            else
+            {
+                fluidState.setSaturation(phase1Idx, priVars[saturationIdx]);
+                fluidState.setSaturation(phase0Idx, 1 - priVars[saturationIdx]);
+                pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
+                fluidState.setPressure(phase0Idx, priVars[pressureIdx] - pc_);
+            }
         }
 
         typename FluidSystem::ParameterCache paramCache;
diff --git a/dumux/porousmediumflow/properties.hh b/dumux/porousmediumflow/properties.hh
index 6ef4ddc262c7c287a08373fe7b0a60e400192cfe..10a5765aee101f6051624a3214728c5341e3473b 100644
--- a/dumux/porousmediumflow/properties.hh
+++ b/dumux/porousmediumflow/properties.hh
@@ -79,6 +79,9 @@ SET_TYPE_PROP(PorousMediumFlow, VelocityOutput, PorousMediumFlowVelocityOutput<T
 SET_TYPE_PROP(PorousMediumFlow, PrimaryVariableSwitch, NoPrimaryVariableSwitch);
 
 SET_BOOL_PROP(PorousMediumFlow, EnableThermalNonEquilibrium, false);
+
+//! Per default, we disable the box interface solver
+SET_BOOL_PROP(PorousMediumFlow, EnableBoxInterfaceSolver, false);
 } // namespace Properties
 } // namespace Dumux