diff --git a/Makefile.am b/Makefile.am
index 1e444ba..05522cf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -121,7 +121,8 @@ pdbg_SOURCES = \
 	src/thread.c \
 	src/util.c \
 	src/util.h \
-	src/err_inject.c
+	src/err_inject.c \
+	src/err_inject.h
 
 pdbg_CFLAGS = -I$(top_srcdir)/libpdbg -Wall -Werror -DGIT_SHA1=\"${GIT_SHA1}\" \
 	      $(ARCH_FLAGS)
diff --git a/src/err_inject.c b/src/err_inject.c
index 23463e7..ef6bc97 100644
--- a/src/err_inject.c
+++ b/src/err_inject.c
@@ -21,26 +21,146 @@
 #include <assert.h>
 
 #include <libpdbg.h>
+#include <ccan/list/list.h>
 
 #include "main.h"
 #include "optcmd.h"
 #include "path.h"
+#include "err_inject.h"
+
+struct list_head error_comp_list = LIST_HEAD_INIT(error_comp_list);
+
+struct error_type {
+	char *name;
+	char *desc;
+	inject_error_t inject_error;
+	void *data;
+	struct list_node error_link;
+};
+
+struct error_comp {
+	char *name;
+	struct list_head err_type_list;
+	struct list_node comp_link;
+};
+
+static struct error_comp *get_error_component(char *component)
+{
+	struct error_comp *err_comp = NULL;
+
+	list_for_each(&error_comp_list, err_comp, comp_link)
+		if (!strcmp(err_comp->name, component))
+			return err_comp;
+	return NULL;
+}
+
+static struct error_comp *create_error_component(char *component)
+{
+	struct error_comp *err_comp = NULL;
+
+	err_comp = malloc(sizeof(*err_comp));
+	if (!err_comp)
+		return NULL;
+
+	err_comp->name = strdup(component);
+	list_head_init(&err_comp->err_type_list);
+	list_add_tail(&error_comp_list, &err_comp->comp_link);
+
+	return err_comp;
+}
+
+static struct error_type *get_error_type(struct error_comp *err_comp,
+							char *error)
+{
+	struct error_type *err_type = NULL;
+
+	list_for_each(&err_comp->err_type_list, err_type, error_link)
+		if (!strcmp(err_type->name, error))
+			return err_type;
+	return NULL;
+}
+
+int register_error_inject(char *component, char *error, char *error_desc,
+				inject_error_t func, void *data)
+{
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		err_comp = create_error_component(component);
+		if (!err_comp)
+			return -ENOMEM;
+	}
+
+	err_type = malloc(sizeof(*err_type));
+	if (!err_type)
+		return -ENOMEM;
+
+	err_type->name = strdup(error);
+	err_type->inject_error = func;
+	err_type->data = data;
+	if (error_desc)
+		err_type->desc = strdup(error_desc);
+	list_add_tail(&err_comp->err_type_list, &err_type->error_link);
+
+	return 0;
+}
 
 static void list_error_components(void)
 {
-	/* TODO: List error components */
+	struct error_comp *err_comp = NULL;
+
+	printf("Usage: pdbg inject <component> <error>\n");
+	printf(" <component>:\n");
+	printf("  %-15s %s\n", "?", "Show component list");
+	list_for_each(&error_comp_list, err_comp, comp_link)
+		printf("  %-15s\n", err_comp->name);
 }
 
 static void list_err_type(char *component)
 {
-	/* TODO: List error type for a give component */
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		printf("Invalid error component: %s\n", component);
+		return;
+	}
+
+	printf("Usage: pdbg inject %s <error>:\n", err_comp->name);
+	printf(" <error>:\n");
+	printf("  %-15s %s\n", "?", "Show error list");
+	list_for_each(&err_comp->err_type_list, err_type, error_link)
+		printf("  %-15s %s\n", err_type->name, err_type->desc);
 }
 
 static void inject_errors(char *component, char *error)
 {
-	/* TODO: Inject errors */
-}
+	struct error_comp *err_comp = NULL;
+	struct error_type *err_type = NULL;
+	struct pdbg_target *target;
 
+	err_comp = get_error_component(component);
+	if (!err_comp) {
+		printf("Invalid error component: %s\n", component);
+		return;
+	}
+
+	err_type = get_error_type(err_comp, error);
+	if (!err_type) {
+		printf("Invalid error type %s for %s\n", error, component);
+		return;
+	}
+
+	for_each_path_target(target) {
+		if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
+			continue;
+
+		err_type->inject_error(target, err_type->data);
+	}
+}
 
 static void error_inject_init(void)
 {
diff --git a/src/err_inject.h b/src/err_inject.h
new file mode 100644
index 0000000..76acee7
--- /dev/null
+++ b/src/err_inject.h
@@ -0,0 +1,20 @@
+#ifndef __ERR_INJECT_H
+#define __ERR_INJECT_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef int (*inject_error_t)(struct pdbg_target *target, void *data);
+
+/**
+ * @brief Register error injections that can be used through pdbg inject
+ *        command
+ * @param[in] component  Name of error component.
+ * @param[in] error      Name of error type under given component.
+ * @param[in] error_desc Description of error to be injected.
+ * @param[in] func       Error injection routine
+ * @param[in] data       Opaque data pointer passed to func.
+ */
+extern int register_error_inject(char *component, char *error,
+			char *error_desc, inject_error_t func, void *data);
+#endif
