diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp
index b1213b29b35ad860734416401bc06c23b3d04d78..f56584b75872d482869796b46b1b4cb4ef5f57ed 100644
--- a/MeshLib/Mesh.cpp
+++ b/MeshLib/Mesh.cpp
@@ -15,6 +15,7 @@
 #include "Mesh.h"
 
 #include <memory>
+#include <unordered_map>
 #include <utility>
 
 #include "BaseLib/RunTime.h"
@@ -337,4 +338,66 @@ void scaleMeshPropertyVector(MeshLib::Mesh & mesh,
         v *= factor;
 }
 
+std::unique_ptr<MeshLib::Mesh> createMeshFromElementSelection(
+    std::string mesh_name, std::vector<MeshLib::Element*> const& elements)
+{
+    DBUG("Found %d elements in the mesh", elements.size());
+
+    // Store bulk element ids for each of the new elements.
+    std::vector<std::size_t> bulk_element_ids;
+    bulk_element_ids.reserve(elements.size());
+    std::transform(begin(elements), end(elements),
+                   std::back_inserter(bulk_element_ids),
+                   [&](auto const& e) { return e->getID(); });
+
+    // original node pointers to newly created nodes.
+    std::unordered_map<const MeshLib::Node*, MeshLib::Node*> nodes_map;
+    nodes_map.reserve(
+        elements.size());  // There will be at least one node per element.
+
+    for (auto& e : elements)
+    {
+        // For each node find a cloned node in map or create if there is none.
+        unsigned const n_nodes = e->getNumberOfNodes();
+        for (unsigned i = 0; i < n_nodes; ++i)
+        {
+            const MeshLib::Node* n = e->getNode(i);
+            auto const it = nodes_map.find(n);
+            if (it == nodes_map.end())
+            {
+                auto new_node_in_map = nodes_map[n] = new MeshLib::Node(*n);
+                e->setNode(i, new_node_in_map);
+            }
+            else
+            {
+                e->setNode(i, it->second);
+            }
+        }
+    }
+
+    // Copy the unique nodes pointers.
+    std::vector<MeshLib::Node*> element_nodes;
+    element_nodes.reserve(nodes_map.size());
+    std::transform(begin(nodes_map), end(nodes_map),
+                   std::back_inserter(element_nodes),
+                   [](auto const& pair) { return pair.second; });
+
+    // Store bulk node ids for each of the new nodes.
+    std::vector<std::size_t> bulk_node_ids;
+    bulk_node_ids.reserve(nodes_map.size());
+    std::transform(begin(nodes_map), end(nodes_map),
+                   std::back_inserter(bulk_node_ids),
+                   [](auto const& pair) { return pair.first->getID(); });
+
+    auto mesh = std::make_unique<MeshLib::Mesh>(
+        std::move(mesh_name), std::move(element_nodes), std::move(elements));
+    assert(mesh != nullptr);
+
+    addPropertyToMesh(*mesh, "bulk_element_ids", MeshLib::MeshItemType::Cell, 1,
+                      bulk_element_ids);
+    addPropertyToMesh(*mesh, "bulk_node_ids", MeshLib::MeshItemType::Node, 1,
+                      bulk_node_ids);
+
+    return mesh;
+}
 }
diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h
index 91f246ab6f9d9fa49738a57b9e0d66119da2d548..e62ba19d36881f546fe13a1bacd8226d8e877e94 100644
--- a/MeshLib/Mesh.h
+++ b/MeshLib/Mesh.h
@@ -15,6 +15,7 @@
 #pragma once
 
 #include <cstdlib>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -285,4 +286,11 @@ PropertyVector<T>* getOrCreateMeshProperty(Mesh& mesh,
     return result;
 }
 
+/// Creates a new mesh from a vector of elements.
+///
+/// \note The elements are owned by the returned mesh object as well as the
+/// nodes and will be destructed together with the mesh.
+std::unique_ptr<MeshLib::Mesh> createMeshFromElementSelection(
+    std::string mesh_name, std::vector<MeshLib::Element*> const& elements);
+
 } /* namespace */