diff --git a/source/libs/lilv/lilv-0.16.0/lilv/lilv.h b/source/libs/lilv/lilv-0.16.0/lilv/lilv.h
index ff1839f..c780326 100644
--- a/source/libs/lilv/lilv-0.16.0/lilv/lilv.h
+++ b/source/libs/lilv/lilv-0.16.0/lilv/lilv.h
@@ -1769,6 +1769,25 @@ const LilvNode*
 lilv_ui_get_binary_uri(const LilvUI* ui);
 
 /**
+  Custom calls
+*/
+LILV_API
+const LilvNodes*
+lilv_ui_get_supported_features(const LilvUI* ui);
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_required_features(const LilvUI* ui);
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_optional_features(const LilvUI* ui);
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_extension_data(const LilvUI* ui);
+
+/**
    @}
    @}
 */
diff --git a/source/libs/lilv/lilv-0.16.0/lilv/lilvmm.hpp b/source/libs/lilv/lilv-0.16.0/lilv/lilvmm.hpp
index 4215ab8..3047930 100644
--- a/source/libs/lilv/lilv-0.16.0/lilv/lilvmm.hpp
+++ b/source/libs/lilv/lilv-0.16.0/lilv/lilvmm.hpp
@@ -169,6 +169,26 @@ struct Port {
 	const LilvPort*   me;
 };
 
+struct UI {
+	inline UI(const LilvUI* c_obj) : me(c_obj) {}
+	LILV_WRAP_CONVERSION(const LilvUI);
+
+	LILV_WRAP0(Node,  ui, get_uri);
+	LILV_WRAP1(bool,  ui, is_a, LilvNode*, ui_class);
+	LILV_WRAP0(Node,  ui, get_bundle_uri);
+	LILV_WRAP0(Node,  ui, get_binary_uri);
+	LILV_WRAP0(Nodes, ui, get_supported_features);
+	LILV_WRAP0(Nodes, ui, get_required_features);
+	LILV_WRAP0(Nodes, ui, get_optional_features);
+	LILV_WRAP0(Nodes, ui, get_extension_data);
+
+	const LilvUI* me;
+};
+
+struct UIs {
+	LILV_WRAP_COLL(UIs, UI, uis);
+};
+
 struct Plugin {
 	inline Plugin(const LilvPlugin* c_obj) : me(c_obj) {}
 	LILV_WRAP_CONVERSION(const LilvPlugin);
diff --git a/source/libs/lilv/lilv-0.16.0/src/ui.c b/source/libs/lilv/lilv-0.16.0/src/ui.c
index 5d2f066..c2780e0 100644
--- a/source/libs/lilv/lilv-0.16.0/src/ui.c
+++ b/source/libs/lilv/lilv-0.16.0/src/ui.c
@@ -128,3 +128,59 @@ lilv_ui_get_binary_uri(const LilvUI* ui)
 	assert(ui->binary_uri);
 	return ui->binary_uri;
 }
+
+static LilvNodes*
+lilv_ui_get_value_internal(const LilvUI* ui,
+                           const SordNode* predicate)
+{
+	assert(ui);
+	return lilv_world_find_nodes_internal(ui->world, ui->uri->node, predicate, NULL);
+}
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_supported_features(const LilvUI* ui)
+{
+	assert(ui);
+	LilvNodes* optional = lilv_ui_get_optional_features(ui);
+	LilvNodes* required = lilv_ui_get_required_features(ui);
+	LilvNodes* result   = lilv_nodes_new();
+
+	LILV_FOREACH(nodes, i, optional)
+		zix_tree_insert((ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(optional, i)), NULL);
+
+	LILV_FOREACH(nodes, i, required)
+		zix_tree_insert((ZixTree*)result, lilv_node_duplicate(lilv_nodes_get(required, i)), NULL);
+
+	lilv_nodes_free(optional);
+	lilv_nodes_free(required);
+
+	return result;
+}
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_required_features(const LilvUI* ui)
+{
+	assert(ui);
+	assert(ui->world);
+	return lilv_ui_get_value_internal(ui, ui->world->uris.lv2_requiredFeature);
+}
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_optional_features(const LilvUI* ui)
+{
+	assert(ui);
+	assert(ui->world);
+	return lilv_ui_get_value_internal(ui, ui->world->uris.lv2_optionalFeature);
+}
+
+LILV_API
+const LilvNodes*
+lilv_ui_get_extension_data(const LilvUI* ui)
+{
+	assert(ui);
+	assert(ui->world);
+	return lilv_ui_get_value_internal(ui, ui->world->uris.lv2_extensionData);
+}
