diff --git a/src/json.hpp b/src/json.hpp
index 6aca24ad..96bc1f32 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8855,7 +8855,6 @@ basic_json_parser_63:
         }
 
       private:
-        /// return referenced value
         reference get(reference j) const
         {
             pointer result = &j;
@@ -8880,6 +8879,49 @@ basic_json_parser_63:
             return *result;
         }
 
+        reference get2(reference j) const
+        {
+            pointer result = &j;
+
+            for (const auto& reference_token : reference_tokens)
+            {
+                switch (result->m_type)
+                {
+                    case value_t::null:
+                    {
+                        if (reference_token == "0")
+                        {
+                            result = &result->operator[](0);
+                        }
+                        else
+                        {
+                            result = &result->operator[](reference_token);
+                        }
+                        continue;
+                    }
+
+                    case value_t::object:
+                    {
+                        result = &result->operator[](reference_token);
+                        continue;
+                    }
+
+                    case value_t::array:
+                    {
+                        result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
+                        continue;
+                    }
+
+                    default:
+                    {
+                        throw std::domain_error("unresolved reference token '" + reference_token + "'");
+                    }
+                }
+            }
+
+            return *result;
+        }
+
         const_reference get(const_reference j) const
         {
             const_pointer result = &j;
@@ -9042,6 +9084,35 @@ basic_json_parser_63:
                 }
             }
         }
+
+        /*!
+        @param[in] value  flattened JSON
+
+        @return deflattened JSON
+        */
+        static basic_json deflatten(const basic_json& value)
+        {
+            if (not value.is_object())
+            {
+                throw std::domain_error("only objects can be deflattened");
+            }
+
+            basic_json result;
+
+            // iterate the JSON object values
+            for (const auto& element : *value.m_value.object)
+            {
+                if (not element.second.is_primitive())
+                {
+                    throw std::domain_error("values in object must be primitive");
+                }
+
+                // assign value to reference pointed to by JSON pointer
+                json_pointer(element.first).get2(result) = element.second;
+            }
+
+            return result;
+        }
     };
 
     /*!
@@ -9053,6 +9124,14 @@ basic_json_parser_63:
         json_pointer::flatten("", *this, result);
         return result;
     }
+
+    /*!
+    @return the original JSON from a flattened version
+    */
+    basic_json deflatten() const
+    {
+        return json_pointer::deflatten(*this);
+    }
 };
 
 
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 74827e2c..1a049cd5 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -8165,7 +8165,6 @@ class basic_json
         }
 
       private:
-        /// return referenced value
         reference get(reference j) const
         {
             pointer result = &j;
@@ -8190,6 +8189,49 @@ class basic_json
             return *result;
         }
 
+        reference get2(reference j) const
+        {
+            pointer result = &j;
+
+            for (const auto& reference_token : reference_tokens)
+            {
+                switch (result->m_type)
+                {
+                    case value_t::null:
+                    {
+                        if (reference_token == "0")
+                        {
+                            result = &result->operator[](0);
+                        }
+                        else
+                        {
+                            result = &result->operator[](reference_token);
+                        }
+                        continue;
+                    }
+
+                    case value_t::object:
+                    {
+                        result = &result->operator[](reference_token);
+                        continue;
+                    }
+
+                    case value_t::array:
+                    {
+                        result = &result->operator[](static_cast<size_t>(std::stoi(reference_token)));
+                        continue;
+                    }
+
+                    default:
+                    {
+                        throw std::domain_error("unresolved reference token '" + reference_token + "'");
+                    }
+                }
+            }
+
+            return *result;
+        }
+
         const_reference get(const_reference j) const
         {
             const_pointer result = &j;
@@ -8352,6 +8394,35 @@ class basic_json
                 }
             }
         }
+
+        /*!
+        @param[in] value  flattened JSON
+
+        @return deflattened JSON
+        */
+        static basic_json deflatten(const basic_json& value)
+        {
+            if (not value.is_object())
+            {
+                throw std::domain_error("only objects can be deflattened");
+            }
+
+            basic_json result;
+
+            // iterate the JSON object values
+            for (const auto& element : *value.m_value.object)
+            {
+                if (not element.second.is_primitive())
+                {
+                    throw std::domain_error("values in object must be primitive");
+                }
+
+                // assign value to reference pointed to by JSON pointer
+                json_pointer(element.first).get2(result) = element.second;
+            }
+
+            return result;
+        }
     };
 
     /*!
@@ -8363,6 +8434,14 @@ class basic_json
         json_pointer::flatten("", *this, result);
         return result;
     }
+
+    /*!
+    @return the original JSON from a flattened version
+    */
+    basic_json deflatten() const
+    {
+        return json_pointer::deflatten(*this);
+    }
 };
 
 
diff --git a/test/unit.cpp b/test/unit.cpp
index 0d9aa0a7..1ace40d0 100644
--- a/test/unit.cpp
+++ b/test/unit.cpp
@@ -12213,7 +12213,24 @@ TEST_CASE("JSON pointers")
             {"/object/~01", "tilde1"}
         };
 
+        // check if flattened result is as expected
         CHECK(j.flatten() == j_flatten);
+
+        // check if deflattened result is as expected
+        CHECK(j_flatten.deflatten() == j);
+
+        // explicit roundtrip check
+        CHECK(j.flatten().deflatten() == j);
+
+        // roundtrip for primitive values
+        json j_null;
+        CHECK(j_null.flatten().deflatten() == j_null);
+        json j_number = 42;
+        CHECK(j_number.flatten().deflatten() == j_number);
+        json j_boolean = false;
+        CHECK(j_boolean.flatten().deflatten() == j_boolean);
+        json j_string = "foo";
+        CHECK(j_string.flatten().deflatten() == j_string);
     }
 }