diff --git a/Applications/ApplicationsLib/ProjectData.cpp b/Applications/ApplicationsLib/ProjectData.cpp
index a035a3fada6418ef29c00aaed21f36225165553d..19c2160f56fd45cdf02ed3622b3bb7953171d71f 100644
--- a/Applications/ApplicationsLib/ProjectData.cpp
+++ b/Applications/ApplicationsLib/ProjectData.cpp
@@ -35,6 +35,7 @@
 #include "ProcessLib/GroundwaterFlow/CreateGroundwaterFlowProcess.h"
 #include "ProcessLib/HeatConduction/CreateHeatConductionProcess.h"
 #include "ProcessLib/RichardsFlow/CreateRichardsFlowProcess.h"
+#include "ProcessLib/LiquidFlow/CreateLiquidFlowProcess.h"
 #include "ProcessLib/SmallDeformation/CreateSmallDeformationProcess.h"
 #include "ProcessLib/SmallDeformationWithLIE/CreateSmallDeformationProcess.h"
 #include "ProcessLib/TES/CreateTESProcess.h"
@@ -292,6 +293,12 @@ void ProjectData::parseProcesses(BaseLib::ConfigTree const& processes_config,
                 _process_variables, _parameters, integration_order,
                 process_config, project_directory, output_directory);
         }
+        else if (type == "LIQUID_FLOW")
+        {
+            process = ProcessLib::LiquidFlow::createLiquidFlowProcess(
+                *_mesh_vec[0], std::move(jacobian_assembler), _process_variables,
+                _parameters, integration_order, process_config);
+        }
         else if (type == "TES")
         {
             process = ProcessLib::TES::createTESProcess(
diff --git a/Applications/CLI/Tests.cmake b/Applications/CLI/Tests.cmake
index 4c4fe0f0a1ade1be5403baf6c82d36b61f54287f..174b023608b0858e1e404cd8b462b6c3a64fbf60 100644
--- a/Applications/CLI/Tests.cmake
+++ b/Applications/CLI/Tests.cmake
@@ -574,6 +574,52 @@ if(NOT OGS_USE_MPI)
         single_joint_inside_expected_pcs_0_ts_1_t_1.000000.vtu single_joint_inside_pcs_0_ts_1_t_1.000000.vtu displacement_jump1 displacement_jump1
     )
 
+    # Liquid flow
+    AddTest(
+        NAME LiquidFlow_LineDirichletNeumannBC
+        PATH Parabolic/LiquidFlow/LineDirichletNeumannBC
+        EXECUTABLE ogs
+        EXECUTABLE_ARGS line_dirichlet_neumannBC.prj
+        WRAPPER time
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        sat1D.vtu sat_1D_pcs_0_ts_1_t_1.000000.vtu AnalyticSolution pressure
+    )
+    AddTest(
+        NAME LiquidFlow_PressureBCatCornerOfAnisotropicSquare
+        PATH Parabolic/LiquidFlow/PressureBCatCornerOfAnisotropicSquare
+        EXECUTABLE ogs
+        EXECUTABLE_ARGS pressureBC_at_corner_of_anisotropic_square.prj
+        WRAPPER time
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        mesh2D.vtu sat_2D_lflow_pcs_0_ts_1_t_1.000000.vtu OGS5_Results pressure
+    )
+    AddTest(
+        NAME LiquidFlow_GravityDriven
+        PATH Parabolic/LiquidFlow/GravityDriven
+        EXECUTABLE ogs
+        EXECUTABLE_ARGS gravity_driven.prj
+        WRAPPER time
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        mesh2D.vtu gravity_driven_pcs_0_ts_1_t_1.000000.vtu AnalyticSolution pressure
+    )
+    AddTest(
+        NAME LiquidFlow_AxisymTheis
+        PATH Parabolic/LiquidFlow/AxiSymTheis
+        EXECUTABLE ogs
+        EXECUTABLE_ARGS axisym_theis.prj
+        WRAPPER time
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        axisym_theis.vtu liquid_pcs_pcs_0_ts_30_t_1728.000000.vtu OGS5_pressure pressure
+    )
+
 else()
     # MPI groundwater flow tests
     AddTest(
@@ -782,4 +828,51 @@ else()
         tes_zeolite_discharge_large_ts_28_t_1_000000.vtu tes_zeolite_discharge_large_pcs_0_ts_28_t_1_000000_0.vtu v_mass_frac v_mass_frac
 #        tes_zeolite_discharge_large_ts_28_t_1_0.vtu solid_density solid_density
     )
+
+    # Liquid flow
+    AddTest(
+        NAME LiquidFlow_LineDirichletNeumannBC
+        PATH Parabolic/LiquidFlow/LineDirichletNeumannBC
+        EXECUTABLE_ARGS line_dirichlet_neumannBC.prj
+        WRAPPER mpirun
+        WRAPPER_ARGS -np 1
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        sat1D.vtu sat_1D_pcs_0_ts_1_t_1.000000.vtu AnalyticSolution pressure
+    )
+    AddTest(
+        NAME LiquidFlow_GravityDriven
+        PATH Parabolic/LiquidFlow/GravityDriven
+        EXECUTABLE_ARGS gravity_driven.prj
+        WRAPPER mpirun
+        WRAPPER_ARGS -np 1
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        mesh2D.vtu gravity_driven_pcs_0_ts_1_t_1.000000.vtu AnalyticSolution pressure
+    )
+    AddTest(
+        NAME LiquidFlow_PressureBCatCornerOfAnisotropicSquare
+        PATH Parabolic/LiquidFlow/PressureBCatCornerOfAnisotropicSquare
+        EXECUTABLE_ARGS pressureBC_at_corner_of_anisotropic_square.prj
+        WRAPPER mpirun
+        WRAPPER_ARGS -np 1
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        mesh2D.vtu sat_2D_lflow_pcs_0_ts_1_t_1.000000.vtu OGS5_Results pressure
+    )
+    AddTest(
+        NAME LiquidFlow_AxisymTheis
+        PATH Parabolic/LiquidFlow/AxiSymTheis
+        EXECUTABLE_ARGS axisym_theis.prj
+        WRAPPER mpirun
+        WRAPPER_ARGS -np 1
+        TESTER vtkdiff
+        ABSTOL 1e-8 RELTOL 1e-8
+        DIFF_DATA
+        axisym_theis.vtu liquid_pcs_pcs_0_ts_30_t_1728.000000.vtu OGS5_pressure pressure
+    )
+
 endif()
diff --git a/ProcessLib/CMakeLists.txt b/ProcessLib/CMakeLists.txt
index 7be84b171a279277277b65758449704dc51ea699..0dd7a458c2bf1ea8f58e376dfebf9662a5c3cf53 100644
--- a/ProcessLib/CMakeLists.txt
+++ b/ProcessLib/CMakeLists.txt
@@ -14,6 +14,8 @@ APPEND_SOURCE_FILES(SOURCES Parameter)
 add_subdirectory(GroundwaterFlow)
 APPEND_SOURCE_FILES(SOURCES GroundwaterFlow)
 
+APPEND_SOURCE_FILES(SOURCES LiquidFlow)
+
 APPEND_SOURCE_FILES(SOURCES SmallDeformation)
 
 APPEND_SOURCE_FILES(SOURCES SmallDeformationWithLIE)
diff --git a/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..78db4b6026b1f452c3a9d8813e20cd6c83e1194a
--- /dev/null
+++ b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.cpp
@@ -0,0 +1,105 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   CreateLiquidFlowProcess.cpp
+ *
+ * Created on August 19, 2016, 1:30 PM
+ */
+#include "CreateLiquidFlowProcess.h"
+
+#include <algorithm>
+
+#include "MeshLib/MeshGenerators/MeshGenerator.h"
+
+#include "ProcessLib/Utils/ParseSecondaryVariables.h"
+#include "ProcessLib/Utils/ProcessUtils.h"
+
+#include "LiquidFlowProcess.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+std::unique_ptr<Process> createLiquidFlowProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config)
+{
+    //! \ogs_file_param{process__type}
+    config.checkConfigParameter("type", "LIQUID_FLOW");
+
+    DBUG("Create LiquidFlowProcess.");
+
+    // Process variable.
+    auto process_variables = findProcessVariables(
+        variables, config,
+        {//! \ogs_file_param_special{process__LIQUID_FLOW__process_variables__process_variable}
+         "process_variable"});
+
+    SecondaryVariableCollection secondary_variables;
+
+    NumLib::NamedFunctionCaller named_function_caller({"LiquidFlow_pressure"});
+
+    ProcessLib::parseSecondaryVariables(config, secondary_variables,
+                                        named_function_caller);
+
+    // Get the gravity vector for the Darcy velocity
+    //! \ogs_file_param{process__LIQUID_FLOW__darcy_gravity}
+    auto const& darcy_g_config = config.getConfigSubtree("darcy_gravity");
+    const int gravity_axis_id_input =
+        //! \ogs_file_param_special{process__LIQUID_FLOW__darcy_gravity_axis_id}
+        darcy_g_config.getConfigParameter<int>("axis_id");
+    assert(gravity_axis_id_input < static_cast<int>(mesh.getDimension()));
+    const double g =
+        //! \ogs_file_param_special{process__LIQUID_FLOW__darcy_gravity_g}
+        darcy_g_config.getConfigParameter<double>("g");
+    assert(g >= 0.);
+    const int gravity_axis_id = (g == 0.) ? -1 : gravity_axis_id_input;
+
+    //! \ogs_file_param{process__LIQUID_FLOW__material_property}
+    auto const& mat_config = config.getConfigSubtree("material_property");
+
+    auto const& mat_ids =
+        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
+    if (mat_ids)
+    {
+        INFO("The liquid flow is in heterogeneous porous media.");
+        const bool has_material_ids = true;
+        return std::unique_ptr<Process>{new LiquidFlowProcess{
+            mesh, std::move(jacobian_assembler), parameters, integration_order,
+            std::move(process_variables), std::move(secondary_variables),
+            std::move(named_function_caller), *mat_ids, has_material_ids,
+            gravity_axis_id, g, mat_config}};
+    }
+    else
+    {
+        INFO("The liquid flow is in homogeneous porous media.");
+
+        MeshLib::Properties dummy_property;
+        // For a reference argument of LiquidFlowProcess(...).
+        auto const& dummy_property_vector =
+            dummy_property.createNewPropertyVector<int>(
+                "MaterialIDs", MeshLib::MeshItemType::Cell, 1);
+
+        // Since dummy_property_vector is only visible in this function,
+        // the following constant, has_material_ids, is employed to indicate
+        // that material_ids does not exist.
+        const bool has_material_ids = false;
+
+        return std::unique_ptr<Process>{new LiquidFlowProcess{
+            mesh, std::move(jacobian_assembler), parameters, integration_order,
+            std::move(process_variables), std::move(secondary_variables),
+            std::move(named_function_caller), *dummy_property_vector,
+            has_material_ids, gravity_axis_id, g, mat_config}};
+    }
+}
+
+}  // end of namespace
+}  // end of namespace
diff --git a/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.h b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e199f53db994f5611d7155901847e2c96f25e2c
--- /dev/null
+++ b/ProcessLib/LiquidFlow/CreateLiquidFlowProcess.h
@@ -0,0 +1,33 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   CreateLiquidFlowProcess.h
+ *
+ * Created on August 19, 2016, 1:30 PM
+ */
+
+#ifndef OGS_CREATELIQUIDFLOWPROCESS_H
+#define OGS_CREATELIQUIDFLOWPROCESS_H
+
+#include <memory>
+#include "ProcessLib/Process.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+std::unique_ptr<Process> createLiquidFlowProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<ProcessLib::AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<ProcessVariable> const& variables,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    BaseLib::ConfigTree const& config);
+}  // end of namespace
+}  // end of namespace
+
+#endif /* CREATELIQUIDFLOWPROCESS_H */
diff --git a/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler-impl.h b/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler-impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..34c42024fdb6badc912870991fdd1e4e6221b3b1
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler-impl.h
@@ -0,0 +1,156 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowLocalAssembler.cpp
+ *
+ * Created on August 19, 2016, 2:28 PM
+ */
+
+#ifndef OGS_LIQUIDFLOWLOCALASSEMBLER_IMPL_H
+#define OGS_LIQUIDFLOWLOCALASSEMBLER_IMPL_H
+
+#include "LiquidFlowLocalAssembler.h"
+
+#include "NumLib/Function/Interpolation.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim>
+void LiquidFlowLocalAssembler<ShapeFunction, IntegrationMethod, GlobalDim>::
+    assemble(double const t, std::vector<double> const& local_x,
+             std::vector<double>& local_M_data,
+             std::vector<double>& local_K_data,
+             std::vector<double>& local_b_data)
+{
+    SpatialPosition pos;
+    pos.setElementID(_element.getID());
+    _material_properties.setMaterialID(pos);
+
+    const Eigen::MatrixXd& perm =
+        _material_properties.getPermeability(t, pos, _element.getDimension());
+    // Note: For Inclined 1D in 2D/3D or 2D element in 3D, the first item in
+    //  the assert must be changed to perm.rows() == _element->getDimension()
+    assert(perm.rows() == GlobalDim || perm.rows() == 1);
+
+    if (perm.size() == 1)  // isotropic or 1D problem.
+        local_assemble<IsotropicLaplacianAndGravityTermCalculator>(
+            t, local_x, local_M_data, local_K_data, local_b_data, pos, perm);
+    else
+        local_assemble<AnisotropicLaplacianAndGravityTermCalculator>(
+            t, local_x, local_M_data, local_K_data, local_b_data, pos, perm);
+}
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim>
+template <typename LaplacianAndGravityTermCalculator>
+void LiquidFlowLocalAssembler<ShapeFunction, IntegrationMethod, GlobalDim>::
+    local_assemble(double const t, std::vector<double> const& local_x,
+                   std::vector<double>& local_M_data,
+                   std::vector<double>& local_K_data,
+                   std::vector<double>& local_b_data,
+                   SpatialPosition const& pos, Eigen::MatrixXd const& perm)
+{
+    auto const local_matrix_size = local_x.size();
+    assert(local_matrix_size == ShapeFunction::NPOINTS);
+
+    auto local_M = MathLib::createZeroedMatrix<NodalMatrixType>(
+        local_M_data, local_matrix_size, local_matrix_size);
+    auto local_K = MathLib::createZeroedMatrix<NodalMatrixType>(
+        local_K_data, local_matrix_size, local_matrix_size);
+    auto local_b = MathLib::createZeroedVector<NodalVectorType>(
+        local_b_data, local_matrix_size);
+
+    unsigned const n_integration_points =
+        _integration_method.getNumberOfPoints();
+
+    // TODO: The following two variables should be calculated inside the
+    //       the integration loop for non-constant porosity and storage models.
+    double porosity_variable = 0.;
+    double storage_variable = 0.;
+    for (unsigned ip = 0; ip < n_integration_points; ip++)
+    {
+        auto const& sm = _shape_matrices[ip];
+        auto const& wp = _integration_method.getWeightedPoint(ip);
+
+        double p = 0.;
+        NumLib::shapeFunctionInterpolate(local_x, sm.N, p);
+        // TODO : compute _temperature from the heat transport pcs
+
+        const double integration_factor =
+            sm.integralMeasure * sm.detJ * wp.getWeight();
+
+        // Assemble mass matrix, M
+        local_M.noalias() +=
+            _material_properties.getMassCoefficient(
+                t, pos, porosity_variable, storage_variable, p, _temperature) *
+            sm.N.transpose() * sm.N * integration_factor;
+
+        // Compute density:
+        const double rho_g =
+            _material_properties.getLiquidDensity(p, _temperature) *
+            _gravitational_acceleration;
+        // Compute viscosity:
+        const double mu = _material_properties.getViscosity(p, _temperature);
+
+        // Assemble Laplacian, K, and RHS by the gravitational term
+        LaplacianAndGravityTermCalculator::calculate(
+            local_K, local_b, sm, perm, integration_factor, mu, rho_g,
+            _gravitational_axis_id);
+    }
+}
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim>
+void LiquidFlowLocalAssembler<ShapeFunction, IntegrationMethod, GlobalDim>::
+    IsotropicLaplacianAndGravityTermCalculator::calculate(
+        Eigen::Map<NodalMatrixType>& local_K,
+        Eigen::Map<NodalVectorType>& local_b, ShapeMatrices const& sm,
+        Eigen::MatrixXd const& perm, double const integration_factor,
+        double const mu, double const rho_g, int const gravitational_axis_id)
+{
+    const double K = perm(0, 0) / mu;
+    const double fac = K * integration_factor;
+    local_K.noalias() += fac * sm.dNdx.transpose() * sm.dNdx;
+
+    if (gravitational_axis_id >= 0)
+    {
+        // Note: Since perm, K, is a scalar number in this function,
+        // (gradN)*K*V becomes K*(grad N)*V. With the gravity vector of V,
+        // the simplification of (grad N)*V is the gravitational_axis_id th
+        // column of the transpose of (grad N) multiplied with rho_g.
+        local_b.noalias() -=
+            fac * sm.dNdx.transpose().col(gravitational_axis_id) * rho_g;
+    }
+}
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim>
+void LiquidFlowLocalAssembler<ShapeFunction, IntegrationMethod, GlobalDim>::
+    AnisotropicLaplacianAndGravityTermCalculator::calculate(
+        Eigen::Map<NodalMatrixType>& local_K,
+        Eigen::Map<NodalVectorType>& local_b, ShapeMatrices const& sm,
+        Eigen::MatrixXd const& perm, double const integration_factor,
+        double const mu, double const rho_g, int const gravitational_axis_id)
+{
+    const double fac = integration_factor / mu;
+    local_K.noalias() += fac * sm.dNdx.transpose() * perm * sm.dNdx;
+    if (gravitational_axis_id >= 0)
+    {
+        // Note: perm * gravity_vector = rho_g * perm.col(gravitational_axis_id)
+        //       i.e the result is the gravitational_axis_id th column of
+        //       perm multiplied with rho_g.
+        local_b.noalias() -=
+            fac * rho_g * sm.dNdx.transpose() * perm.col(gravitational_axis_id);
+    }
+}
+}  // end of namespace
+}  // end of namespace
+
+#endif /* OGS_LIQUIDFLOWLOCALASSEMBLER_IMPL_H */
diff --git a/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler.h b/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b34deaa09d3a3d943147f8d9bb0672be49daf96
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowLocalAssembler.h
@@ -0,0 +1,178 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowLocalAssembler.h
+ *
+ * Created on August 19, 2016, 2:28 PM
+ */
+
+#ifndef OGS_LIQUIDFLOWLOCALASSEMBLER_H
+#define OGS_LIQUIDFLOWLOCALASSEMBLER_H
+
+#include <vector>
+
+#include "MathLib/LinAlg/Eigen/EigenMapTools.h"
+#include "NumLib/Extrapolation/ExtrapolatableElement.h"
+#include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h"
+#include "NumLib/Fem/ShapeMatrixPolicy.h"
+#include "ProcessLib/LocalAssemblerInterface.h"
+#include "ProcessLib/LocalAssemblerTraits.h"
+#include "ProcessLib/Parameter/Parameter.h"
+#include "ProcessLib/Utils/InitShapeMatrices.h"
+
+#include "LiquidFlowMaterialProperties.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+const unsigned NUM_NODAL_DOF = 1;
+
+class LiquidFlowLocalAssemblerInterface
+    : public ProcessLib::LocalAssemblerInterface,
+      public NumLib::ExtrapolatableElement
+{
+public:
+    virtual std::vector<double> const& getIntPtDarcyVelocityX(
+        std::vector<double>& /*cache*/) const = 0;
+
+    virtual std::vector<double> const& getIntPtDarcyVelocityY(
+        std::vector<double>& /*cache*/) const = 0;
+
+    virtual std::vector<double> const& getIntPtDarcyVelocityZ(
+        std::vector<double>& /*cache*/) const = 0;
+};
+
+template <typename ShapeFunction, typename IntegrationMethod,
+          unsigned GlobalDim>
+class LiquidFlowLocalAssembler : public LiquidFlowLocalAssemblerInterface
+{
+    using ShapeMatricesType = ShapeMatrixPolicyType<ShapeFunction, GlobalDim>;
+    using ShapeMatrices = typename ShapeMatricesType::ShapeMatrices;
+
+    using LocalAssemblerTraits = ProcessLib::LocalAssemblerTraits<
+        ShapeMatricesType, ShapeFunction::NPOINTS, NUM_NODAL_DOF, GlobalDim>;
+
+    using NodalMatrixType = typename LocalAssemblerTraits::LocalMatrix;
+    using NodalVectorType = typename LocalAssemblerTraits::LocalVector;
+    using GlobalDimVectorType = typename ShapeMatricesType::GlobalDimVectorType;
+
+public:
+    LiquidFlowLocalAssembler(MeshLib::Element const& element,
+                             std::size_t const /*local_matrix_size*/,
+                             bool const is_axially_symmetric,
+                             unsigned const integration_order,
+                             int const gravitational_axis_id,
+                             double const gravitational_acceleration,
+                             LiquidFlowMaterialProperties& material_propertries)
+        : _element(element),
+          _integration_method(integration_order),
+          _shape_matrices(initShapeMatrices<ShapeFunction, ShapeMatricesType,
+                                            IntegrationMethod, GlobalDim>(
+              element, is_axially_symmetric, _integration_method)),
+          _gravitational_axis_id(gravitational_axis_id),
+          _gravitational_acceleration(gravitational_acceleration),
+          _material_properties(material_propertries)
+    {
+    }
+
+    void assemble(double const t, std::vector<double> const& local_x,
+                  std::vector<double>& local_M_data,
+                  std::vector<double>& local_K_data,
+                  std::vector<double>& local_b_data) override;
+
+    Eigen::Map<const Eigen::RowVectorXd> getShapeMatrix(
+        const unsigned integration_point) const override
+    {
+        auto const& N = _shape_matrices[integration_point].N;
+
+        // assumes N is stored contiguously in memory
+        return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
+    }
+
+    std::vector<double> const& getIntPtDarcyVelocityX(
+        std::vector<double>& /*cache*/) const override
+    {
+        assert(_darcy_velocities.size() > 0);
+        return _darcy_velocities[0];
+    }
+
+    std::vector<double> const& getIntPtDarcyVelocityY(
+        std::vector<double>& /*cache*/) const override
+    {
+        assert(_darcy_velocities.size() > 1);
+        return _darcy_velocities[1];
+    }
+
+    std::vector<double> const& getIntPtDarcyVelocityZ(
+        std::vector<double>& /*cache*/) const override
+    {
+        assert(_darcy_velocities.size() > 2);
+        return _darcy_velocities[2];
+    }
+
+private:
+    MeshLib::Element const& _element;
+
+    IntegrationMethod const _integration_method;
+    std::vector<ShapeMatrices> _shape_matrices;
+
+    std::vector<std::vector<double>> _darcy_velocities =
+        std::vector<std::vector<double>>(
+            GlobalDim,
+            std::vector<double>(_integration_method.getNumberOfPoints()));
+
+    /**
+     *  Calculator of the Laplacian and the gravity term for anisotropic
+     *  permeability tensor
+     */
+    struct AnisotropicLaplacianAndGravityTermCalculator
+    {
+        static void calculate(Eigen::Map<NodalMatrixType>& local_K,
+                              Eigen::Map<NodalVectorType>& local_b,
+                              ShapeMatrices const& sm,
+                              Eigen::MatrixXd const& perm,
+                              double const integration_factor, double const mu,
+                              double const rho_g,
+                              int const gravitational_axis_id);
+    };
+
+    /**
+     *  Calculator of the Laplacian and the gravity term for isotropic
+     *  permeability tensor
+     */
+    struct IsotropicLaplacianAndGravityTermCalculator
+    {
+        static void calculate(Eigen::Map<NodalMatrixType>& local_K,
+                              Eigen::Map<NodalVectorType>& local_b,
+                              ShapeMatrices const& sm,
+                              Eigen::MatrixXd const& perm,
+                              double const integration_factor, double const mu,
+                              double const rho_g,
+                              int const gravitational_axis_id);
+    };
+
+    template <typename LaplacianAndGravityTermCalculator>
+    void local_assemble(double const t, std::vector<double> const& local_x,
+                        std::vector<double>& local_M_data,
+                        std::vector<double>& local_K_data,
+                        std::vector<double>& local_b_data,
+                        SpatialPosition const& pos,
+                        Eigen::MatrixXd const& perm);
+
+    const int _gravitational_axis_id;
+    const double _gravitational_acceleration;
+    LiquidFlowMaterialProperties& _material_properties;
+    double _temperature;
+};
+
+}  // end of namespace
+}  // end of namespace
+
+#include "LiquidFlowLocalAssembler-impl.h"
+
+#endif /* LIQUIDFLOWLOCALASSEMBLER_H */
diff --git a/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.cpp b/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..063a1cfb6cd8a11f08e883c46db9d9c092f43788
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.cpp
@@ -0,0 +1,140 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowMaterialProperties.cpp
+ *
+ * Created on August 18, 2016, 11:49 AM
+ */
+
+#include "LiquidFlowMaterialProperties.h"
+
+#include <logog/include/logog.hpp>
+
+#include "BaseLib/reorderVector.h"
+
+#include "MeshLib/PropertyVector.h"
+
+#include "ProcessLib/Parameter/Parameter.h"
+#include "ProcessLib/Parameter/SpatialPosition.h"
+
+#include "MaterialLib/Fluid/FluidProperty.h"
+#include "MaterialLib/PorousMedium/Porosity/Porosity.h"
+#include "MaterialLib/PorousMedium/Storage/Storage.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+LiquidFlowMaterialProperties::LiquidFlowMaterialProperties(
+    BaseLib::ConfigTree const& config,
+    bool const has_material_ids,
+    MeshLib::PropertyVector<int> const& material_ids)
+    : _has_material_ids(has_material_ids), _material_ids(material_ids)
+{
+    DBUG("Reading material properties of liquid flow process.");
+
+    //! \ogs_file_param{prj__material_property__fluid}
+    auto const& fluid_config = config.getConfigSubtree("fluid");
+
+    // Get fluid properties
+    //! \ogs_file_param{prj__material_property__fluid__density}
+    auto const& rho_conf = fluid_config.getConfigSubtree("density");
+    _liquid_density = MaterialLib::Fluid::createFluidDensityModel(rho_conf);
+    //! \ogs_file_param{prj__material_property__fluid__viscosity}
+    auto const& mu_conf = fluid_config.getConfigSubtree("viscosity");
+    _viscosity = MaterialLib::Fluid::createViscosityModel(mu_conf);
+
+    // Get porous properties
+    std::vector<int> mat_ids;
+    //! \ogs_file_param{prj__material_property__porous_medium}
+    auto const& poro_config = config.getConfigSubtree("porous_medium");
+    //! \ogs_file_param{prj__material_property__porous_medium__porous_medium}
+    for (auto const& conf : poro_config.getConfigSubtreeList("porous_medium"))
+    {
+        //! \ogs_file_attr{prj__material_property__porous_medium__porous_medium__id}
+        auto const id = conf.getConfigAttributeOptional<int>("id");
+        mat_ids.push_back(*id);
+
+        //! \ogs_file_param{prj__material_property__porous_medium__porous_medium__permeability}
+        auto const& perm_conf = conf.getConfigSubtree("permeability");
+        _intrinsic_permeability_models.emplace_back(
+            MaterialLib::PorousMedium::createPermeabilityModel(perm_conf));
+
+        //! \ogs_file_param{prj__material_property__porous_medium__porous_medium__porosity}
+        auto const& poro_conf = conf.getConfigSubtree("porosity");
+        auto n = MaterialLib::PorousMedium::createPorosityModel(poro_conf);
+        _porosity_models.emplace_back(std::move(n));
+
+        //! \ogs_file_param{prj__material_property__porous_medium__porous_medium__storage}
+        auto const& stora_conf = conf.getConfigSubtree("storage");
+        auto beta = MaterialLib::PorousMedium::createStorageModel(stora_conf);
+        _storage_models.emplace_back(std::move(beta));
+    }
+
+    BaseLib::reorderVector(_intrinsic_permeability_models, mat_ids);
+    BaseLib::reorderVector(_porosity_models, mat_ids);
+    BaseLib::reorderVector(_storage_models, mat_ids);
+}
+
+void LiquidFlowMaterialProperties::setMaterialID(const SpatialPosition& pos)
+{
+    if (!_has_material_ids)
+    {
+        _current_material_id = 0;
+        return;
+    }
+
+    assert(pos.getElementID().get() < _material_ids.size());
+    _current_material_id = _material_ids[pos.getElementID().get()];
+}
+
+double LiquidFlowMaterialProperties::getLiquidDensity(const double p,
+                                                      const double T) const
+{
+    ArrayType vars;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::T)] = T;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::pl)] = p;
+    return _liquid_density->getValue(vars);
+}
+
+double LiquidFlowMaterialProperties::getViscosity(const double p,
+                                                  const double T) const
+{
+    ArrayType vars;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::T)] = T;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::pl)] = p;
+    return _viscosity->getValue(vars);
+}
+
+double LiquidFlowMaterialProperties::getMassCoefficient(
+    const double /*t*/, const SpatialPosition& /*pos*/, const double p,
+    const double T, const double porosity_variable,
+    const double storage_variable) const
+{
+    ArrayType vars;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::T)] = T;
+    vars[static_cast<int>(MaterialLib::Fluid::PropertyVariableType::pl)] = p;
+    const double drho_dp = _liquid_density->getdValue(
+        vars, MaterialLib::Fluid::PropertyVariableType::pl);
+    const double rho = _liquid_density->getValue(vars);
+    assert(rho > 0.);
+
+    const double porosity =
+        _porosity_models[_current_material_id]->getValue(porosity_variable, T);
+    const double storage =
+        _storage_models[_current_material_id]->getValue(storage_variable);
+    return porosity * drho_dp / rho + storage;
+}
+
+Eigen::MatrixXd const& LiquidFlowMaterialProperties::getPermeability(
+    const double /*t*/, const SpatialPosition& /*pos*/, const int /*dim*/) const
+{
+    return _intrinsic_permeability_models[_current_material_id];
+}
+
+}  // end of namespace
+}  // end of namespace
diff --git a/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.h b/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf26617da8b62430396231f363247656d3f70291
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.h
@@ -0,0 +1,109 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowMaterialProperties.h
+ *
+ * Created on August 18, 2016, 11:03 AM
+ */
+
+#ifndef OGS_LIQUIDFLOWMATERIALPROPERTIES_H
+#define OGS_LIQUIDFLOWMATERIALPROPERTIES_H
+
+#include <memory>
+
+#include "MaterialLib/Fluid/FluidPropertyHeaders.h"
+#include "MaterialLib/PorousMedium/PorousPropertyHeaders.h"
+
+namespace MaterialLib
+{
+namespace PorousMedium
+{
+class Porosity;
+class Storage;
+}
+}
+
+namespace MeshLib
+{
+template <typename PROP_VAL_TYPE>
+class PropertyVector;
+}
+
+namespace ProcessLib
+{
+class SpatialPosition;
+
+namespace LiquidFlow
+{
+class LiquidFlowMaterialProperties
+{
+public:
+    typedef MaterialLib::Fluid::FluidProperty::ArrayType ArrayType;
+
+    LiquidFlowMaterialProperties(
+        BaseLib::ConfigTree const& config,
+        bool const has_material_ids,
+        MeshLib::PropertyVector<int> const& material_ids);
+
+    void setMaterialID(const SpatialPosition& pos);
+
+    /**
+     * \brief Compute the coefficient of the mass term by
+     *      \f[
+     *           n \frac{partial \rho_l}{\partial p} + \beta_s
+     *      \f]
+     *     where \f$n\f$ is the porosity, \f$rho_l\f$ is the liquid density,
+     *     \f$bata_s\f$ is the storage.
+     * \param t                  Time.
+     * \param pos                Position of element.
+     * \param p                  Pressure value.
+     * \param T                  Temperature value.
+     * \param porosity_variable  The first variable for porosity model, and it
+     *                           passes a double type value that could be
+     *                           saturation, and invariant of stress or strain.
+     * \param storage_variable   Variable for storage model.
+     */
+    double getMassCoefficient(const double t, const SpatialPosition& pos,
+                              const double p, const double T,
+                              const double porosity_variable,
+                              const double storage_variable) const;
+
+    Eigen::MatrixXd const& getPermeability(const double t,
+                                           const SpatialPosition& pos,
+                                           const int dim) const;
+
+    double getLiquidDensity(const double p, const double T) const;
+
+    double getViscosity(const double p, const double T) const;
+
+private:
+    std::unique_ptr<MaterialLib::Fluid::FluidProperty> _liquid_density;
+    std::unique_ptr<MaterialLib::Fluid::FluidProperty> _viscosity;
+
+    /// A flag to indicate whether the reference member, _material_ids,
+    /// is not assigned.
+    const bool _has_material_ids;
+    /** Use porous medium models for different material zones.
+     *  Material IDs must be given as mesh element properties.
+     */
+    MeshLib::PropertyVector<int> const& _material_ids;
+
+    int _current_material_id = 0;
+    std::vector<Eigen::MatrixXd> _intrinsic_permeability_models;
+    std::vector<std::unique_ptr<MaterialLib::PorousMedium::Porosity>>
+        _porosity_models;
+    std::vector<std::unique_ptr<MaterialLib::PorousMedium::Storage>>
+        _storage_models;
+
+    // Note: For the statistical data of porous media, they could be read from
+    // vtu files directly. This can be done by using property vectors directly.
+    // Such property vectors will be added here if they are needed.
+};
+
+}  // end of namespace
+}  // end of namespace
+#endif /* LIQUIDFLOWMATERIALPROPERTIES_H */
diff --git a/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp b/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..603d30d776f173bae0aeacfd59fc543cb988d7a6
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowProcess.cpp
@@ -0,0 +1,115 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowProcess.cpp
+ *
+ * Created on August 19, 2016, 1:38 PM
+ */
+
+#include "LiquidFlowProcess.h"
+
+#include <cassert>
+
+#include "MeshLib/PropertyVector.h"
+
+#include "ProcessLib/Utils/CreateLocalAssemblers.h"
+#include "LiquidFlowLocalAssembler.h"
+
+#include "MaterialLib/PorousMedium/Porosity/Porosity.h"
+#include "MaterialLib/PorousMedium/Storage/Storage.h"
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+LiquidFlowProcess::LiquidFlowProcess(
+    MeshLib::Mesh& mesh,
+    std::unique_ptr<AbstractJacobianAssembler>&& jacobian_assembler,
+    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+    unsigned const integration_order,
+    std::vector<std::reference_wrapper<ProcessVariable>>&& process_variables,
+    SecondaryVariableCollection&& secondary_variables,
+    NumLib::NamedFunctionCaller&& named_function_caller,
+    MeshLib::PropertyVector<int> const& material_ids,
+    bool const has_material_ids,
+    int const gravitational_axis_id,
+    double const gravitational_acceleration,
+    BaseLib::ConfigTree const& config)
+    : Process(mesh, std::move(jacobian_assembler), parameters,
+              integration_order, std::move(process_variables),
+              std::move(secondary_variables), std::move(named_function_caller)),
+      _gravitational_axis_id(gravitational_axis_id),
+      _gravitational_acceleration(gravitational_acceleration),
+      _material_properties(
+          LiquidFlowMaterialProperties(config, has_material_ids, material_ids))
+{
+    DBUG("Create Liquid flow process.");
+}
+
+void LiquidFlowProcess::initializeConcreteProcess(
+    NumLib::LocalToGlobalIndexMap const& dof_table,
+    MeshLib::Mesh const& mesh,
+    unsigned const integration_order)
+{
+    ProcessLib::createLocalAssemblers<LiquidFlowLocalAssembler>(
+        mesh.getDimension(), mesh.getElements(), dof_table, _local_assemblers,
+        mesh.isAxiallySymmetric(), integration_order, _gravitational_axis_id,
+        _gravitational_acceleration, _material_properties);
+
+    _secondary_variables.addSecondaryVariable(
+        "darcy_velocity_x", 1,
+        makeExtrapolator(
+            getExtrapolator(), _local_assemblers,
+            &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityX));
+
+    if (mesh.getDimension() > 1)
+    {
+        _secondary_variables.addSecondaryVariable(
+            "darcy_velocity_y", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityY));
+    }
+    if (mesh.getDimension() > 2)
+    {
+        _secondary_variables.addSecondaryVariable(
+            "darcy_velocity_z", 1,
+            makeExtrapolator(
+                getExtrapolator(), _local_assemblers,
+                &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityZ));
+    }
+}
+
+void LiquidFlowProcess::assembleConcreteProcess(const double t,
+                                                GlobalVector const& x,
+                                                GlobalMatrix& M,
+                                                GlobalMatrix& K,
+                                                GlobalVector& b)
+{
+    DBUG("Assemble LiquidFlowProcess.");
+    // Call global assembler for each local assembly item.
+    GlobalExecutor::executeMemberDereferenced(
+        _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers,
+        *_local_to_global_index_map, t, x, M, K, b);
+}
+
+void LiquidFlowProcess::assembleWithJacobianConcreteProcess(
+    const double t, GlobalVector const& x, GlobalVector const& xdot,
+    const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K,
+    GlobalVector& b, GlobalMatrix& Jac)
+{
+    DBUG("AssembleWithJacobian LiquidFlowProcess.");
+
+    // Call global assembler for each local assembly item.
+    GlobalExecutor::executeMemberDereferenced(
+        _global_assembler, &VectorMatrixAssembler::assembleWithJacobian,
+        _local_assemblers, *_local_to_global_index_map, t, x, xdot, dxdot_dx,
+        dx_dx, M, K, b, Jac);
+}
+
+}  // end of namespace
+}  // end of namespace
diff --git a/ProcessLib/LiquidFlow/LiquidFlowProcess.h b/ProcessLib/LiquidFlow/LiquidFlowProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff1a5aac2052550c6cfd6c6cf592925b79c09ffc
--- /dev/null
+++ b/ProcessLib/LiquidFlow/LiquidFlowProcess.h
@@ -0,0 +1,98 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   LiquidFlowProcess.h
+ *
+ * Created on August 19, 2016, 1:38 PM
+ */
+
+#ifndef OGS_LIQUIDFLOWPROCESS_H
+#define OGS_LIQUIDFLOWPROCESS_H
+
+#include "NumLib/DOF/LocalToGlobalIndexMap.h"
+#include "ProcessLib/Process.h"
+
+#include "LiquidFlowMaterialProperties.h"
+#include "LiquidFlowLocalAssembler.h"
+
+namespace MeshLib
+{
+class Element;
+class Mesh;
+template <typename PROP_VAL_TYPE>
+class PropertyVector;
+}
+
+namespace ProcessLib
+{
+namespace LiquidFlow
+{
+/**
+ * \brief A class to simulate the liquid flow process in porous media described
+ * by
+ *
+ * \f[
+ *     \frac{\partial n \rho_l}{\partial T} \frac{\partial T}{\partial t}/\rho_l
+ *       + (\frac{\partial n \rho_l}{\partial p}/\rho_l + \beta_s)
+ *          \frac{\partial p}{\partial t}
+ *       -\nabla (\frac{K}{\mu}(\nabla p + \rho_l g \nabla z) ) = Q
+ * \f]
+ * where
+ *    \f{eqnarray*}{
+ *       &p:&        \mbox{pore pressure,}\\
+ *       &T: &       \mbox{Temperature,}\\
+ *       &\rho_l:&   \mbox{liquid density,}\\
+ *       &\beta_s:&  \mbox{specific storage,}\\
+ *       &K:&        \mbox{permeability,}\\
+ *       &\mu:&      \mbox{viscosity,}\\
+ *    \f}
+ */
+class LiquidFlowProcess final : public Process
+{
+public:
+    LiquidFlowProcess(
+        MeshLib::Mesh& mesh,
+        std::unique_ptr<AbstractJacobianAssembler>&& jacobian_assembler,
+        std::vector<std::unique_ptr<ParameterBase>> const& parameters,
+        unsigned const integration_order,
+        std::vector<std::reference_wrapper<ProcessVariable>>&&
+            process_variables,
+        SecondaryVariableCollection&& secondary_variables,
+        NumLib::NamedFunctionCaller&& named_function_caller,
+        MeshLib::PropertyVector<int> const& material_ids,
+        bool const has_material_ids,
+        int const gravitational_axis_id,
+        double const gravitational_acceleration,
+        BaseLib::ConfigTree const& config);
+
+    bool isLinear() const override { return true; }
+private:
+    void initializeConcreteProcess(
+        NumLib::LocalToGlobalIndexMap const& dof_table,
+        MeshLib::Mesh const& mesh, unsigned const integration_order) override;
+
+    void assembleConcreteProcess(const double t, GlobalVector const& x,
+                                 GlobalMatrix& M, GlobalMatrix& K,
+                                 GlobalVector& b) override;
+
+    void assembleWithJacobianConcreteProcess(
+        const double t, GlobalVector const& x, GlobalVector const& xdot,
+        const double dxdot_dx, const double dx_dx, GlobalMatrix& M,
+        GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) override;
+
+    const int _gravitational_axis_id;
+    const double _gravitational_acceleration;
+    LiquidFlowMaterialProperties _material_properties;
+
+    std::vector<std::unique_ptr<LiquidFlowLocalAssemblerInterface>>
+        _local_assemblers;
+};
+
+}  // end of namespace
+}  // end of namespace
+
+#endif /* LIQUIDFLOWPROCESS_H */
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 18735e31f903a258203f56e7611765d5415df94b..cb082141837322f0e774d2e63dbf3dea16ad2cd1 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -18,6 +18,7 @@ APPEND_SOURCE_FILES(TEST_SOURCES MeshLib)
 APPEND_SOURCE_FILES(TEST_SOURCES MeshGeoToolsLib)
 APPEND_SOURCE_FILES(TEST_SOURCES NumLib)
 APPEND_SOURCE_FILES(TEST_SOURCES ProcessLib)
+APPEND_SOURCE_FILES(TEST_SOURCES ProcessLib/LiquidFlow)
 
 if(QT4_FOUND)
     APPEND_SOURCE_FILES(TEST_SOURCES FileIO_Qt)
diff --git a/Tests/Data b/Tests/Data
index 6de9e6af6d103d65054b2f2b16f6d6b49a53aeaf..d6ca72279bdc1275b7ccd98b7e47fdbd8cc7acfa 160000
--- a/Tests/Data
+++ b/Tests/Data
@@ -1 +1 @@
-Subproject commit 6de9e6af6d103d65054b2f2b16f6d6b49a53aeaf
+Subproject commit d6ca72279bdc1275b7ccd98b7e47fdbd8cc7acfa
diff --git a/Tests/ProcessLib/LiquidFlow/TestLiquidFlowMaterialProperties.cpp b/Tests/ProcessLib/LiquidFlow/TestLiquidFlowMaterialProperties.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..830711966af4e9543285f804ac6eccb2256b1d17
--- /dev/null
+++ b/Tests/ProcessLib/LiquidFlow/TestLiquidFlowMaterialProperties.cpp
@@ -0,0 +1,101 @@
+/**
+ * \copyright
+ * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ * \file   TestLiquidFlowMaterialProperties.cpp
+ *
+ * Created on August 18, 2016, 4:53 PM
+ */
+
+#include <gtest/gtest.h>
+#include <memory>
+
+#include "TestTools.h"
+
+#include "MeshLib/Mesh.h"
+#include "MeshLib/MeshGenerators/MeshGenerator.h"
+
+#include "ProcessLib/Parameter/SpatialPosition.h"
+#include "ProcessLib/LiquidFlow/LiquidFlowMaterialProperties.h"
+
+#include "MaterialLib/Fluid/FluidProperty.h"
+#include "MaterialLib/PorousMedium/Porosity/Porosity.h"
+#include "MaterialLib/PorousMedium/Storage/Storage.h"
+
+using namespace ProcessLib::LiquidFlow;
+using namespace MaterialLib::Fluid;
+using ArrayType = MaterialLib::Fluid::FluidProperty::ArrayType;
+using Matrix = Eigen::MatrixXd;
+
+TEST(ProcessLibLiquidFlow, checkLiquidFlowMaterialProperties)
+{
+    const char xml[] =
+        "<material_property>"
+        "    <fluid>"
+        "        <density>"
+        "           <type>LiquidDensity</type>"
+        "           <temperature0> 273.15 </temperature0>"
+        "           <p0> 1.e+5 </p0> "
+        "           <bulk_modulus> 2.15e+9 </bulk_modulus>"
+        "           <beta> 2.0e-4 </beta> "
+        "           <rho0>999.8</rho0>"
+        "        </density>"
+        "        <viscosity>"
+        "            <type>Vogels</type>"
+        "            <liquid_type>Water </liquid_type>"
+        "        </viscosity>"
+        "    </fluid>"
+        "    <porous_medium>"
+        "        <porous_medium  id=\"0\">"
+        "            <permeability>"
+        "              <values>2.e-10 0. 0. 0. 3.e-10 0. 0. 0. 4.0e-10</values>"
+        "            </permeability>"
+        "            <porosity>"
+        "                <type>Constant</type>"
+        "                <value> 0.2 </value> "
+        "            </porosity>"
+        "            <storage>"
+        "                <type>Constant</type>"
+        "                <value> 1.e-4 </value>"
+        "            </storage>"
+        "        </porous_medium>"
+        "    </porous_medium>"
+        "</material_property>";
+
+    auto const ptree = readXml(xml);
+    BaseLib::ConfigTree conf(ptree, "", BaseLib::ConfigTree::onerror,
+                             BaseLib::ConfigTree::onwarning);
+    auto const& sub_config = conf.getConfigSubtree("material_property");
+
+    MeshLib::Properties dummy_property;
+    auto const& dummy_property_vector =
+        dummy_property.createNewPropertyVector<int>(
+            "MaterialIDs", MeshLib::MeshItemType::Cell, 1);
+
+    const bool has_material_ids = false;
+    LiquidFlowMaterialProperties lprop(sub_config, has_material_ids,
+                                       *dummy_property_vector);
+
+    ProcessLib::SpatialPosition pos;
+    pos.setElementID(0);
+
+    // Check permeability
+    const Eigen::MatrixXd& perm = lprop.getPermeability(0., pos, 1);
+    ASSERT_EQ(2.e-10, perm(0, 0));
+    ASSERT_EQ(0., perm(0, 1));
+    ASSERT_EQ(0., perm(0, 2));
+    ASSERT_EQ(0., perm(1, 0));
+    ASSERT_EQ(3.e-10, perm(1, 1));
+    ASSERT_EQ(0., perm(1, 2));
+    ASSERT_EQ(0., perm(2, 0));
+    ASSERT_EQ(0., perm(2, 1));
+    ASSERT_EQ(4.e-10, perm(2, 2));
+
+    const double T = 273.15 + 60.0;
+    const double p = 1.e+6;
+    const double mass_coef = lprop.getMassCoefficient(0., pos, p, T, 0., 0.);
+    ASSERT_NEAR(0.000100000093, mass_coef, 1.e-10);
+}