diff --git a/Spigot-API-Patches/Add-TNT-source-location-API.patch b/Spigot-API-Patches/Add-TNT-source-location-API.patch
new file mode 100644
index 0000000000..682e1691b9
--- /dev/null
+++ b/Spigot-API-Patches/Add-TNT-source-location-API.patch
@@ -0,0 +1,23 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Sun, 30 Nov 2014 22:57:17 -0600
+Subject: [PATCH] Add TNT source location API
+
+
+diff --git a/src/main/java/org/bukkit/entity/TNTPrimed.java b/src/main/java/org/bukkit/entity/TNTPrimed.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/entity/TNTPrimed.java
++++ b/src/main/java/org/bukkit/entity/TNTPrimed.java
+@@ -0,0 +0,0 @@ public interface TNTPrimed extends Explosive {
+      * @return the source of this primed TNT
+      */
+     public Entity getSource();
++
++    /**
++     * Gets the source block location of the primed TNT.
++     *
++     * @return the source block location the TNT was spawned from
++     */
++    public org.bukkit.Location getSourceLoc();
+ }
+--
\ No newline at end of file
diff --git a/Spigot-Server-Patches/Add-TNT-source-location-API.patch b/Spigot-Server-Patches/Add-TNT-source-location-API.patch
new file mode 100644
index 0000000000..22dc5a45f5
--- /dev/null
+++ b/Spigot-Server-Patches/Add-TNT-source-location-API.patch
@@ -0,0 +1,130 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Sun, 30 Nov 2014 22:57:18 -0600
+Subject: [PATCH] Add TNT source location API
+
+
+diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/BlockTNT.java
++++ b/src/main/java/net/minecraft/server/BlockTNT.java
+@@ -0,0 +0,0 @@ public class BlockTNT extends Block {
+ 
+     public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) {
+         if (!world.isStatic) {
+-            EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), explosion.c());
++            org.bukkit.Location loc = explosion.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) explosion.source).sourceLoc : new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot
++            EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), explosion.c()); // PaperSpigot - add loc
+ 
+             entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8;
+             world.addEntity(entitytntprimed);
+@@ -0,0 +0,0 @@ public class BlockTNT extends Block {
+     public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving) {
+         if (!world.isStatic) {
+             if (((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue()) {
+-                EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), entityliving);
++                org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot
++                EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), entityliving); // PaperSpigot - add loc
+ 
+                 world.addEntity(entitytntprimed);
+                 world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F);
+diff --git a/src/main/java/net/minecraft/server/DispenseBehaviorTNT.java b/src/main/java/net/minecraft/server/DispenseBehaviorTNT.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/DispenseBehaviorTNT.java
++++ b/src/main/java/net/minecraft/server/DispenseBehaviorTNT.java
+@@ -0,0 +0,0 @@ final class DispenseBehaviorTNT extends DispenseBehaviorItem {
+             }
+         }
+ 
+-        EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null);
++        EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(block.getLocation(), world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); // PaperSpigot
+         // CraftBukkit end
+ 
+         world.addEntity(entitytntprimed);
+diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java
++++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
+@@ -0,0 +0,0 @@ public class EntityTNTPrimed extends Entity {
+     private EntityLiving source;
+     public float yield = 4; // CraftBukkit - add field
+     public boolean isIncendiary = false; // CraftBukkit - add field
++    public org.bukkit.Location sourceLoc; // PaperSpigot
+ 
++    // PaperSpigot start - TNT source location API
+     public EntityTNTPrimed(World world) {
++        this(null, world);
++    }
++
++    public EntityTNTPrimed(org.bukkit.Location loc, World world) {
++    // PaperSpigot end
+         super(world);
++        sourceLoc = loc; // PaperSpigot
+         this.k = true;
+         this.a(0.98F, 0.98F);
+     }
+ 
+-    public EntityTNTPrimed(World world, double d0, double d1, double d2, EntityLiving entityliving) {
+-        this(world);
++    public EntityTNTPrimed(org.bukkit.Location loc, World world, double d0, double d1, double d2, EntityLiving entityliving) {
++        this(loc, world);
+         this.setPosition(d0, d1, d2);
+         //float f = (float) (Math.random() * 3.1415927410125732D * 2.0D); // PaperSpigot - Fix directional TNT bias
+ 
+@@ -0,0 +0,0 @@ public class EntityTNTPrimed extends Entity {
+ 
+     protected void b(NBTTagCompound nbttagcompound) {
+         nbttagcompound.setByte("Fuse", (byte) this.fuseTicks);
++        // PaperSpigot start - TNT source location API
++        if (sourceLoc != null) {
++            nbttagcompound.setInt("SourceLoc_x", sourceLoc.getBlockX());
++            nbttagcompound.setInt("SourceLoc_y", sourceLoc.getBlockY());
++            nbttagcompound.setInt("SourceLoc_z", sourceLoc.getBlockZ());
++        }
++        // PaperSpigot end
+     }
+ 
+     protected void a(NBTTagCompound nbttagcompound) {
+         this.fuseTicks = nbttagcompound.getByte("Fuse");
++        // PaperSpigot start - TNT source location API
++        if (nbttagcompound.hasKey("SourceLoc_x")) {
++            int srcX = nbttagcompound.getInt("SourceLoc_x");
++            int srcY = nbttagcompound.getInt("SourceLoc_y");
++            int srcZ = nbttagcompound.getInt("SourceLoc_z");
++            sourceLoc = new org.bukkit.Location(world.getWorld(), srcX, srcY, srcZ);
++        }
++        // PaperSpigot end
+     }
+ 
+     public EntityLiving getSource() {
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -0,0 +0,0 @@ public class CraftWorld implements World {
+                 throw new IllegalArgumentException("Cannot spawn hanging entity for " + clazz.getName() + " at " + location);
+             }
+         } else if (TNTPrimed.class.isAssignableFrom(clazz)) {
+-            entity = new EntityTNTPrimed(world, x, y, z, null);
++            org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), x, y, z); // PaperSpigot
++            entity = new EntityTNTPrimed(loc, world, x, y, z, null);
+         } else if (ExperienceOrb.class.isAssignableFrom(clazz)) {
+             entity = new EntityExperienceOrb(world, x, y, z, 0);
+         } else if (Weather.class.isAssignableFrom(clazz)) {
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java
+@@ -0,0 +0,0 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed {
+ 
+         return null;
+     }
++
++    // PaperSpigot start
++    @Override
++    public org.bukkit.Location getSourceLoc() {
++        return getHandle().sourceLoc;
++    }
++    // PaperSpigot end
+ }
+--
\ No newline at end of file