data FEATURE add lyd_new_ext_term()
diff --git a/doc/transition.dox b/doc/transition.dox
index 0bcc338..aac54cc 100644
--- a/doc/transition.dox
+++ b/doc/transition.dox
@@ -354,6 +354,7 @@
  * lyd_new(), lyd_new_output()  | ::lyd_new_inner(), ::lyd_new_list(), ::lyd_new_list2() | Redesigned functionality to better fit new lyd_node structures, creating RPC's output data is now done via a flag parameter of the functions.
  * lyd_new_leaf(), lyd_new_output_leaf() | ::lyd_new_term()       | ^
  * lyd_new_anydata(), lyd_new_output_anydata() | ::lyd_new_any()  | ^
+ * -                            | ::lyd_new_ext_term()            | Additional functionality to lyd_new_* functions to cover top-level nodes in extension instances.
  * lyd_insert_attr()            | ::lyd_new_meta()                | Unify naming used in other functions with the similar functionality.
  * -                            | ::lyd_new_attr()                | Added functionality to store the data (temporarily) not connected with schema definitions.
  * -                            | ::lyd_new_attr2()               | ^
diff --git a/src/tree_data.c b/src/tree_data.c
index ea1a658..069d94c 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -974,8 +974,7 @@
     schema = lys_find_child(parent ? parent->schema : NULL, module, name, 0, LYD_NODE_TERM, output ? LYS_GETNEXT_OUTPUT : 0);
     LY_CHECK_ERR_RET(!schema, LOGERR(ctx, LY_EINVAL, "Term node \"%s\" not found.", name), LY_ENOTFOUND);
 
-    rc = lyd_create_term(schema, val_str, val_str ? strlen(val_str) : 0, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL,
-            &ret);
+    rc = lyd_create_term(schema, val_str, val_str ? strlen(val_str) : 0, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL, &ret);
     LY_CHECK_RET(rc);
     if (parent) {
         lyd_insert_node(parent, NULL, ret);
@@ -988,6 +987,34 @@
 }
 
 API LY_ERR
+lyd_new_ext_term(const struct lysc_ext_instance *ext, const char *name, const char *val_str, struct lyd_node **node)
+{
+    LY_ERR rc;
+    struct lyd_node *ret = NULL;
+    const struct lysc_node *schema;
+    struct ly_ctx *ctx = ext ? ext->module->ctx : NULL;
+
+    LY_CHECK_ARG_RET(ctx, ext, node, name, LY_EINVAL);
+
+    schema = lysc_ext_find_node(ext, NULL, name, 0, LYD_NODE_TERM, 0);
+    if (!schema) {
+        if (ext->argument) {
+            LOGERR(ctx, LY_EINVAL, "Term node \"%s\" not found in instance \"%s\" of extension %s.",
+                    name, ext->argument, ext->def->name);
+        } else {
+            LOGERR(ctx, LY_EINVAL, "Term node \"%s\" not found in instance of extension %s.", name, ext->def->name);
+        }
+        return LY_ENOTFOUND;
+    }
+    rc = lyd_create_term(schema, val_str, val_str ? strlen(val_str) : 0, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, NULL, &ret);
+    LY_CHECK_RET(rc);
+
+    *node = ret;
+
+    return LY_SUCCESS;
+}
+
+API LY_ERR
 lyd_new_any(struct lyd_node *parent, const struct lys_module *module, const char *name, const void *value,
         ly_bool use_value, LYD_ANYDATA_VALUETYPE value_type, ly_bool output, struct lyd_node **node)
 {
diff --git a/src/tree_data.h b/src/tree_data.h
index 44f8aad..83b4729 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -125,6 +125,11 @@
  * about the modified data, and is generally simpler to use. Actually the third way is duplicating the existing data using
  * ::lyd_dup_single(), ::lyd_dup_siblings() and ::lyd_dup_meta_single().
  *
+ * Note, that in case the node is defined in an extension instance, the functions mentioned above do not work until you
+ * provide parent where the new node is supposed to be inserted. The reason is that all the functions searches for the
+ * top-level nodes directly inside modules. To create a top-level node defined in an extension instance, use
+ * ::lyd_new_ext_term() function.
+ *
  * The [metadata](@ref howtoPluginsExtensionsMetadata) (and attributes in opaq nodes) can be created with ::lyd_new_meta()
  * and ::lyd_new_attr().
  *
@@ -168,6 +173,8 @@
  * - ::lyd_new_path()
  * - ::lyd_new_path2()
  *
+ * - ::lyd_new_ext_term()
+ *
  * - ::lyd_dup_single()
  * - ::lyd_dup_siblings()
  * - ::lyd_dup_meta_single()
@@ -947,6 +954,8 @@
 /**
  * @brief Create a new term node in the data tree.
  *
+ * To create a top-level term node defined in an extension instance, use ::lyd_new_ext_term().
+ *
  * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
  * @param[in] module Module of the node being created. If NULL, @p parent module will be used.
  * @param[in] name Schema node name of the new data node. The node can be #LYS_LEAF or #LYS_LEAFLIST.
@@ -961,6 +970,21 @@
         ly_bool output, struct lyd_node **node);
 
 /**
+ * @brief Create a new top-level term node defined in the given extension instance.
+ *
+ * To create a term node with parent (no matter if defined inside extension instance or a standard tree) or a top-level
+ * node of a standard module's tree, use ::lyd_new_term().
+ *
+ * @param[in] ext Extension instance where the term node being created is defined.
+ * @param[in] name Schema node name of the new data node. The node can be #LYS_LEAF or #LYS_LEAFLIST.
+ * @param[in] val_str String form of the value of the node being created. In case of an instance-identifier or identityref
+ * value, the JSON format is expected (module names instead of prefixes).
+ * @param[out] node The created node.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_new_ext_term(const struct lysc_ext_instance *ext, const char *name, const char *val_str, struct lyd_node **node);
+
+/**
  * @brief Create a new any node in the data tree.
  *
  * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.