diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
index cf59d75..86662d7 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java
@@ -127,6 +127,8 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
         register(new DummyProperty<>("look_distance", configManager.getConfig().lookPropertyDistance()));
         register(new DummyProperty<>("view_distance", configManager.getConfig().viewDistance()));
 
+        register(new DummyProperty<>("permission_required", false));
+
         register(new GlowProperty(packetFactory));
         register(new BitsetProperty("fire", 0, 0x01));
         register(new BitsetProperty("invisible", 0, 0x20));
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
index e7ff2a1..846e420 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java
@@ -115,7 +115,7 @@ public class NpcTypeImpl implements NpcType {
         public NpcTypeImpl build() {
             ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
             addProperties("fire", "invisible", "silent", "look", "look_distance", "view_distance",
-                    "potion_color", "potion_ambient", "display_name");
+                    "potion_color", "potion_ambient", "display_name", "permission_required");
             if (!type.equals(EntityTypes.PLAYER)) addProperties("dinnerbone");
             // TODO: make this look nicer after completing the rest of the properties
             if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow");
diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java
index 2f45c55..054daaa 100644
--- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java
+++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java
@@ -30,6 +30,7 @@ public class NpcProcessorTask extends BukkitRunnable {
         EntityPropertyImpl<Integer> viewDistanceProperty = propertyRegistry.getByName("view_distance", Integer.class); // Not sure why this is an Integer, but it is
         EntityPropertyImpl<LookType> lookProperty = propertyRegistry.getByName("look", LookType.class);
         EntityPropertyImpl<Double> lookDistanceProperty = propertyRegistry.getByName("look_distance", Double.class);
+        EntityPropertyImpl<Boolean> permissionRequiredProperty = propertyRegistry.getByName("permission_required", Boolean.class);
         double lookDistance;
         for (NpcEntryImpl entry : npcRegistry.getProcessable()) {
             NpcImpl npc = entry.getNpc();
@@ -39,11 +40,16 @@ public class NpcProcessorTask extends BukkitRunnable {
             Player closest = null;
             LookType lookType = npc.getProperty(lookProperty);
             lookDistance =  NumberConversions.square(npc.getProperty(lookDistanceProperty));
+            boolean permissionRequired = npc.getProperty(permissionRequiredProperty);
             for (Player player : Bukkit.getOnlinePlayers()) {
                 if (!player.getWorld().equals(npc.getWorld())) {
                     if (npc.isVisibleTo(player)) npc.hide(player);
                     continue;
                 }
+                if (permissionRequired && !player.hasPermission("znpcsplus.npc." + entry.getId())) {
+                    if (npc.isVisibleTo(player)) npc.hide(player);
+                    continue;
+                }
                 double distance = player.getLocation().distanceSquared(npc.getBukkitLocation());
 
                 // visibility