diff --git a/contrib/restrict_create_commands/Makefile b/contrib/restrict_create_commands/Makefile
new file mode 100644
index 0000000..81c1d70
--- /dev/null
+++ b/contrib/restrict_create_commands/Makefile
@@ -0,0 +1,18 @@
+# contrib/restrict_create_commands/Makefile
+
+MODULE_big = restrict_create_commands
+OBJS = restrict_create_commands.o $(WIN32RES)
+PGFILEDESC = "restrict_create_commands - Extension to restrict specific create commands for normal user"
+
+LDFLAGS_SL += $(filter -lm, $(LIBS))
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/restrict_create_commands
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/contrib/restrict_create_commands/restrict_create_commands.c b/contrib/restrict_create_commands/restrict_create_commands.c
new file mode 100644
index 0000000..3dcf9b2
--- /dev/null
+++ b/contrib/restrict_create_commands/restrict_create_commands.c
@@ -0,0 +1,144 @@
+/*-------------------------------------------------------------------------
+ *
+ * restrict_create_commands.c
+ *
+ * Module to restrict some specific CREATE commands from normal
+ * users
+ *
+ * Copyright (c) 2016, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  contrib/restrict_create_commands/restrict_create_commands.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "miscadmin.h"
+#include "tcop/utility.h"
+
+PG_MODULE_MAGIC;
+
+/* Saved hook values in case of unload */
+static ProcessUtility_hook_type prev_ProcessUtility = NULL;
+
+bool enable_restrict_create_commands = false;
+
+/*---- Function declarations ----*/
+
+void		_PG_init(void);
+void		_PG_fini(void);
+
+static void restrict_ProcessUtility(Node *parseTree, const char *queryString,
+						ProcessUtilityContext context, ParamListInfo params,
+						DestReceiver *dest, char *completionTag);
+static void check_restricted_command(Node *parseTree);
+
+/*
+ * Module load callback
+ */
+void
+_PG_init(void)
+{
+	/*
+	 * we have to be loaded via shared_preload_libraries. If not, fall out
+	 * without hooking into any of the main system.
+	 */
+	if (!process_shared_preload_libraries_in_progress)
+		return;
+
+	DefineCustomBoolVariable("restrict_create_commands.enable",
+	   "Enable to restrict specific create commands from normal users.",
+							 NULL,
+							 &enable_restrict_create_commands,
+							 false,
+							 PGC_SIGHUP,
+							 0,
+							 NULL,
+							 NULL,
+							 NULL);
+
+	/*
+	 * Install hooks.
+	 */
+	prev_ProcessUtility = ProcessUtility_hook;
+	ProcessUtility_hook = restrict_ProcessUtility;
+}
+
+/*
+ * Module unload callback
+ */
+void
+_PG_fini(void)
+{
+	/* Uninstall hooks. */
+	ProcessUtility_hook = prev_ProcessUtility;
+}
+
+
+/*
+ * ProcessUtility hook
+ */
+static void
+restrict_ProcessUtility(Node *parseTree, const char *queryString,
+						ProcessUtilityContext context, ParamListInfo params,
+						DestReceiver *dest, char *completionTag)
+{
+
+	if (superuser() || !enable_restrict_create_commands)
+	{
+		standard_ProcessUtility(parseTree, queryString,
+								context, params,
+								dest, completionTag);
+		return;
+	}
+
+	check_restricted_command(parseTree);
+
+	if (prev_ProcessUtility)
+		prev_ProcessUtility(parseTree, queryString,
+							context, params,
+							dest, completionTag);
+	else
+		standard_ProcessUtility(parseTree, queryString,
+								context, params,
+								dest, completionTag);
+	return;
+}
+
+/*
+ * check_restricted_command
+ *
+ * Restrict the following operations.
+ * CREATE FUNCTION, CREATE AGGREGATE, CREATE VIEW, CREATE OPERATOR
+ * CREATE TRIGGER, CREATE POLICY
+ */
+static void
+check_restricted_command(Node *parseTree)
+{
+	switch (nodeTag(parseTree))
+	{
+		case T_CreateFunctionStmt:
+		case T_CreateTrigStmt:
+		case T_CreatePolicyStmt:
+		case T_ViewStmt:
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("command operation is restricted")));
+				break;
+		case T_DefineStmt:
+		{
+			DefineStmt *n = (DefineStmt *)parseTree;
+			if ((n->kind == OBJECT_OPERATOR)
+				|| (n->kind == OBJECT_AGGREGATE))
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("command operation is restricted")));
+			break;
+		}
+
+		default:
+			break;
+	}
+}
