diff --git a/README.md b/README.md
index ef4b00a29d70503728f7d007f8795210691a19a9..63c879afaed1f971f8f8b535eef961d3f5dceadb 100644
--- a/README.md
+++ b/README.md
@@ -81,27 +81,29 @@ root@iopsys:~# ubus -v list usp
         "del_object":{"path":"String","proto":"String","key":"String","instance_mode":"Integer"}
 root@iopsys:~#
 root@iopsys:~# ubus -v list usp.raw
-'usp.raw' @fcd59dcd
-        "dump_schema":{}
-        "list_operate":{}
-        "get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
-        "getm_values":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
-        "getm_names":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
-        "getm_attributes":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
-        "object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
-        "instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
-        "validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
-        "transaction_start":{"app":"String"}
-        "set":{"path":"String","value":"String","values":"Table","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
-        "operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
-        "add_object":{"path":"String","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
-        "del_object":{"path":"String","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
-        "setm_values":{"pv_tuple":"Array","proto":"String","instance_mode":"Integer","key":"String","transaction_id":"Integer"}
-        "setm_attributes":{"paths":"Array","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
-        "transaction_commit":{"transaction_id":"Integer"}
-        "transaction_abort":{"transaction_id":"Integer"}
-        "transaction_status":{"transaction_id":"Integer"}
-        "list_notify":{"instance_mode":"Integer"}
+'usp.raw' @08a13407
+	"dump_schema":{}
+	"list_operate":{}
+	"list_events":{}
+	"get":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
+	"getm_values":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
+	"getm_names":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
+	"getm_attributes":{"paths":"Array","proto":"String","next-level":"Boolean","instance_mode":"Integer"}
+	"object_names":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
+	"instances":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
+	"validate":{"path":"String","proto":"String","maxdepth":"Integer","next-level":"Boolean","instance_mode":"Integer"}
+	"transaction_start":{"app":"String"}
+	"set":{"path":"String","value":"String","values":"Table","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
+	"operate":{"path":"String","action":"String","input":"Table","proto":"String","instance_mode":"Integer"}
+	"add_object":{"path":"String","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
+	"del_object":{"path":"String","proto":"String","key":"String","instance_mode":"Integer","transaction_id":"Integer"}
+	"setm_values":{"pv_tuple":"Array","proto":"String","instance_mode":"Integer","key":"String","transaction_id":"Integer"}
+	"setm_attributes":{"paths":"Array","proto":"String","instance_mode":"Integer","transaction_id":"Integer"}
+	"transaction_commit":{"transaction_id":"Integer"}
+	"transaction_abort":{"transaction_id":"Integer"}
+	"transaction_status":{"transaction_id":"Integer"}
+	"list_notify":{"instance_mode":"Integer"}
+	"notify_event":{"name":"String","input":"Table"}
 root@iopsys:~#
 ```
 
@@ -233,6 +235,8 @@ root@iopsys:~#
  17. Transaction commit
  18. Transaction abort
  19. List notification objects
+ 20. List supported usp events
+ 21. Send notification for an event
 
 It also provide a granularity layer which can be configured using uci parameter and provide additional ubus objects.
 
@@ -953,6 +957,32 @@ root@iopsys:~# ubus call usp.raw list_notify
 }
 ```
 
+### 20. List supported events
+API to list down the data-model events for usp notification.
+
+```bash
+root@iopsys:~# ubus call usp.raw list_events
+{
+	"parameters": [
+		{
+			"parameter": "Device.LocalAgent.TransferComplete!",
+			"in": [
+				"Command",
+				"CommandKey",
+				"Requestor",
+				"TransferType",
+				"Affected",
+				"TransferURL",
+				"StartTime",
+				"CompleteTime",
+				"FaultCode",
+				"FaultString"
+			]
+		}
+	]
+}
+```
+
 ## Path syntax and possible error cases
 Please note some error scenerios with the uspd.
 
diff --git a/schemas/ubus/usp.raw.json b/schemas/ubus/usp.raw.json
index da1b99f7d8e6677e3e8edb9fee027b6dc1cbc4f4..3d45a9ecbfbc1c6deccc3ee96720c6463f7054bb 100644
--- a/schemas/ubus/usp.raw.json
+++ b/schemas/ubus/usp.raw.json
@@ -243,6 +243,46 @@
         }
       }
     },
+    "list_events": {
+      "title": "List down supported usp events",
+      "description": "events will be shown in schema format",
+      "type": "object",
+      "properties": {
+        "input": {
+          "type": "object",
+	  "properties": {}
+        },
+        "output": {
+          "type": "object",
+          "required": [
+            "parameters"
+          ],
+          "properties": {
+            "parameters": {
+              "type": "array",
+              "items": [{
+                "type": "object",
+                "required": [
+                  "parameter",
+                  "type"
+                ],
+                "properties": {
+                  "parameter": {
+                    "$ref": "#/definitions/operate_path_t"
+                  },
+                  "in": {
+                    "type": "array",
+                    "items": [{
+                      "type": "string"
+                    }]
+                  }
+                }
+              }]
+            }
+          }
+        }
+      }
+    },
     "get": {
       "title": "Get handler",
       "description": "Query the datamodel object",
diff --git a/src/Makefile b/src/Makefile
index a3c2b186fd79668a6b8528bd759f56db6cb1b30d..e09af2c2938fbb7a6b68af41574e51c5b85951c4 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
 PROG = uspd
-OBJS =common.o get.o get_helper.o set.o operate.o add_delete.o pretty_print.o usp.o
+OBJS =common.o get.o get_helper.o set.o operate.o add_delete.o pretty_print.o usp.o events.o
 CP=cp -f
 
 PROG_CFLAGS = $(CFLAGS) \
diff --git a/src/events.c b/src/events.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd640b9caafacba578deb21fdab50c57b40e529b
--- /dev/null
+++ b/src/events.c
@@ -0,0 +1,88 @@
+/*
+ * events.c: Handler to generate usp events on ubus
+ *
+ * Copyright (C) 2021 iopsys Software Solutions AB. All rights reserved.
+ *
+ * Author: Vivek Dutta <vivek.dutta@iopsys.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "common.h"
+#include "events.h"
+#include <libubus.h>
+
+struct event {
+	const char *path;
+	const char **params;
+};
+
+static const struct event supp_events[] = {
+	{
+		.path = "Device.LocalAgent.TransferComplete!", 
+		.params = (const char *[]) {
+			"Command",
+			"CommandKey",
+			"Requestor",
+			"TransferType",
+			"Affected",
+			"TransferURL",
+			"StartTime",
+			"CompleteTime",
+			"FaultCode",
+			"FaultString",
+			NULL
+		}
+	}
+};
+
+void list_event_schema(struct blob_buf *bb)
+{
+	void *array, *table, *array_arg;
+	size_t i, j;
+	const struct event *ev;
+
+	array = blobmsg_open_array(bb, "parameters");
+	for (i = 0; i < ARRAY_SIZE(supp_events); i++) {
+		ev = &supp_events[i];
+		table = blobmsg_open_table(bb, NULL);
+		blobmsg_add_string(bb, "parameter", ev->path);
+		// filling params
+		if (ev->params) {
+			array_arg = blobmsg_open_array(bb, "in");
+			for (j = 0; ev->params[j] != NULL; j++)
+				blobmsg_add_string(bb, NULL, ev->params[j]);
+
+			blobmsg_close_array(bb, array_arg);
+		}
+		blobmsg_close_table(bb, table);
+	}
+
+	blobmsg_close_array(bb, array);
+}
+
+bool is_registered_event(char *name)
+{
+	const struct event *ev;
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(supp_events); i++) {
+		ev = &supp_events[i];
+		if (strcmp(name, ev->path) == 0)
+			return true;
+	}
+
+	return false;
+}
diff --git a/src/events.h b/src/events.h
new file mode 100644
index 0000000000000000000000000000000000000000..31c28fc0f067f914ac4d38ad2ca791dc8d01475f
--- /dev/null
+++ b/src/events.h
@@ -0,0 +1,9 @@
+#ifndef EVENT_H
+#define EVENT_H
+
+#include "usp.h"
+#include "common.h"
+
+void list_event_schema(struct blob_buf *bb);
+bool is_registered_event(char *name);
+#endif /* EVENT_H */
diff --git a/src/usp.c b/src/usp.c
index 85a3ee3d7298008c42121efff7592f2a423ad180..98e55ff8105f2e6ef0c7a6ea2e4db1c939252ed9 100644
--- a/src/usp.c
+++ b/src/usp.c
@@ -1,7 +1,7 @@
 /*
  * usp.c: USP deamon
  *
- * Copyright (C) 2019 iopsys Software Solutions AB. All rights reserved.
+ * Copyright (C) 2021 iopsys Software Solutions AB. All rights reserved.
  *
  * Author: Vivek Dutta <vivek.dutta@iopsys.eu>
  *
@@ -42,6 +42,7 @@
 #include "add_delete.h"
 #include "strncpyt.h"
 #include "ipc.h"
+#include "events.h"
 
 
 static int uspd_start_deferred(usp_data_t *data,
@@ -867,6 +868,50 @@ int usp_list_operate(struct ubus_context *actx, struct ubus_object *obj,
 	return 0;
 }
 
+static const struct blobmsg_policy dm_notify_event_policy[] = {
+	[DM_NOTIFY_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+	[DM_NOTIFY_PRAMS] = { .name = "input", .type = BLOBMSG_TYPE_TABLE },
+};
+
+int usp_notify_event(struct ubus_context *ctx, struct ubus_object *obj,
+		    struct ubus_request_data *req __attribute__((unused)), const char *method,
+		    struct blob_attr *msg)
+{
+	struct blob_attr *tb[__DM_NOTIFY_MAX] = {NULL};
+	char *event_name;
+
+	if (blobmsg_parse(dm_notify_event_policy, __DM_NOTIFY_MAX, tb, blob_data(msg), blob_len(msg))) {
+		ERR("Failed to parse blob");
+		return UBUS_STATUS_UNKNOWN_ERROR;
+	}
+
+	if (!tb[DM_NOTIFY_NAME])
+		return UBUS_STATUS_INVALID_ARGUMENT;
+
+	INFO("ubus method|%s|, name|%s|", method, obj->name);
+	event_name = blobmsg_get_string(tb[DM_NOTIFY_NAME]);
+	if (is_registered_event(event_name)) {
+		ubus_send_event(ctx, "usp.event", msg);
+	} else {
+		WARNING("Event %s not registered", event_name);
+	}
+
+	return 0;
+}
+
+int usp_list_events(struct ubus_context *actx, struct ubus_object *obj,
+		     struct ubus_request_data *req, const char *method,
+		     struct blob_attr *msg __attribute__((unused)))
+{
+	struct usp_context *u;
+
+	INFO("ubus method|%s|, name|%s|", method, obj->name);
+	u = container_of(actx, struct usp_context, ubus_ctx);
+	ubus_send_reply(actx, req, u->event_schema_bb.head);
+
+	return 0;
+}
+
 static const struct blobmsg_policy dm_list_notify_policy[] = {
 	[DM_LIST_NOTIFY_INSTANCE] = { .name = "instance_mode", .type = BLOBMSG_TYPE_INT32 },
 };
@@ -1050,6 +1095,7 @@ int usp_transaction_handler(struct ubus_context *ctx, struct ubus_object *obj,
 static struct ubus_method usp_raw_methods[] = {
 	UBUS_METHOD_NOARG("dump_schema", usp_list_schema),
 	UBUS_METHOD_NOARG("list_operate", usp_list_operate),
+	UBUS_METHOD_NOARG("list_events", usp_list_events),
 	UBUS_METHOD("get", usp_get_handler, dm_get_policy),
 	UBUS_METHOD("getm_values", usp_getm_values, dm_getm_policy),
 	UBUS_METHOD("getm_names", usp_getm_names, dm_getm_policy),
@@ -1068,6 +1114,7 @@ static struct ubus_method usp_raw_methods[] = {
 	UBUS_METHOD("transaction_abort", usp_transaction_handler, trans_policy),
 	UBUS_METHOD("transaction_status", usp_transaction_handler, trans_policy),
 	UBUS_METHOD("list_notify", usp_list_notify, dm_list_notify_policy),
+	UBUS_METHOD("notify_event", usp_notify_event, dm_notify_event_policy),
 };
 
 static void test_client_subscribe_cb(USP_ATTR_UNUSED struct ubus_context *ctx,
@@ -1202,9 +1249,11 @@ bool usp_pre_init(struct usp_context *u)
 	// Initialise blobs
 	blob_buf_init(&u->schema_bb, 0);
 	blob_buf_init(&u->operate_schema_bb, 0);
+	blob_buf_init(&u->event_schema_bb, 0);
 
 	// Get schema
 	list_operate_schema(&u->operate_schema_bb);
+	list_event_schema(&u->event_schema_bb);
 	ret = bbf_dm_get_schema(&u->schema_bb);
 	if (ret != 0)
 		return false;
@@ -1283,6 +1332,7 @@ bool usp_cleanup(struct usp_context *u)
 {
 	blob_buf_free(&u->schema_bb);
 	blob_buf_free(&u->operate_schema_bb);
+	blob_buf_free(&u->event_schema_bb);
 	free_ubus_obj_list(&u->obj_list);
 	free_dynamic_arrays();
 
diff --git a/src/usp.h b/src/usp.h
index 69c02f799759d04d20accbb7c2dc42f54d447870..3c4b9a932a379b757e52b3ef127ebe249b3b3f6c 100644
--- a/src/usp.h
+++ b/src/usp.h
@@ -22,6 +22,7 @@ struct usp_context {
 	struct ubus_context ubus_ctx;
 	struct blob_buf schema_bb;
 	struct blob_buf operate_schema_bb;
+	struct blob_buf event_schema_bb;
 	struct uloop_timeout schema_timer;
 	struct ubus_object *notify_object;
 	struct list_head obj_list;
@@ -50,6 +51,12 @@ enum {
 	__DM_LIST_NOTIFY_MAX,
 };
 
+enum {
+	DM_NOTIFY_NAME,
+	DM_NOTIFY_PRAMS,
+	__DM_NOTIFY_MAX,
+};
+
 struct obNode {
 	struct ubus_object *obj;
 	struct list_head list;
diff --git a/test/files/etc/config/cwmp b/test/files/etc/config/cwmp
index 567717d596c15b55aa3d4b9f4337950055ff3799..d44752ccc1f0e2d8dd67b8abb35adb6383155cda 100644
--- a/test/files/etc/config/cwmp
+++ b/test/files/etc/config/cwmp
@@ -29,7 +29,6 @@ config cpe 'cpe'
 	option userid '' #$OUI-$SER
 	option passwd 'iopsys'
 	option port '7547'
-	option ubus_socket '/var/run/ubus.sock'
 	option provisioning_code ''
 	option amd_version '5'
 	# compression possible configs: InstanceNumber, InstanceAlias
diff --git a/test/python/validate_ubus_event.py b/test/python/validate_ubus_event.py
new file mode 100755
index 0000000000000000000000000000000000000000..84601605aec52a220ee43dc11355bc24d211624c
--- /dev/null
+++ b/test/python/validate_ubus_event.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python3
+
+import ubus
+import json
+
+TEST_NAME = "Validate ubus event usp.raw"
+
+print("Running: " + TEST_NAME)
+
+def callback(event, data):
+    print("PASS: " + TEST_NAME)
+    ubus.disconnect()
+    exit(0)
+    
+assert ubus.connect()
+
+ubus.listen(("usp.event", callback))
+
+ubus.call("usp.raw", "notify_event", {"name":"Device.LocalAgent.TransferComplete!", "input":{"param1":"val1", "param2":"val2"}})
+
+ubus.loop()
+
+ubus.disconnect()
+
+print("FAIL: " + TEST_NAME)