--- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
+++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java
@@ -10,14 +10,22 @@
 import net.minecraft.world.entity.EntityType;
 import net.minecraft.world.entity.LivingEntity;
 import net.minecraft.world.entity.monster.Endermite;
+import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.Items;
 import net.minecraft.world.level.GameRules;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.phys.EntityHitResult;
 import net.minecraft.world.phys.HitResult;
+// CraftBukkit start
+import org.bukkit.Bukkit;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+// CraftBukkit end
 
 public class ThrownEnderpearl extends ThrowableItemProjectile {
+
     public ThrownEnderpearl(EntityType<? extends ThrownEnderpearl> type, Level world) {
         super(type, world);
     }
@@ -41,66 +49,76 @@
     protected void onHit(HitResult hitResult) {
         super.onHit(hitResult);
 
-        for (int i = 0; i < 32; i++) {
-            this.level()
-                .addParticle(
-                    ParticleTypes.PORTAL,
-                    this.getX(),
-                    this.getY() + this.random.nextDouble() * 2.0,
-                    this.getZ(),
-                    this.random.nextGaussian(),
-                    0.0,
-                    this.random.nextGaussian()
-                );
+        for (int i = 0; i < 32; ++i) {
+            this.level().addParticle(ParticleTypes.PORTAL, this.getX(), this.getY() + this.random.nextDouble() * 2.0D, this.getZ(), this.random.nextGaussian(), 0.0D, this.random.nextGaussian());
         }
 
         if (!this.level().isClientSide && !this.isRemoved()) {
             Entity entity = this.getOwner();
-            if (entity instanceof ServerPlayer serverPlayer) {
-                if (serverPlayer.connection.isAcceptingMessages() && serverPlayer.level() == this.level() && !serverPlayer.isSleeping()) {
-                    if (this.random.nextFloat() < 0.05F && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
-                        Endermite endermite = EntityType.ENDERMITE.create(this.level());
-                        if (endermite != null) {
-                            endermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
-                            this.level().addFreshEntity(endermite);
+
+            if (entity instanceof ServerPlayer) {
+                ServerPlayer entityplayer = (ServerPlayer) entity;
+
+                if (entityplayer.connection.isAcceptingMessages() && entityplayer.level() == this.level() && !entityplayer.isSleeping()) {
+                    // CraftBukkit start - Fire PlayerTeleportEvent
+                    org.bukkit.craftbukkit.entity.CraftPlayer player = entityplayer.getBukkitEntity();
+                    org.bukkit.Location location = this.getBukkitEntity().getLocation();
+                    location.setPitch(player.getLocation().getPitch());
+                    location.setYaw(player.getLocation().getYaw());
+
+                    PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, PlayerTeleportEvent.TeleportCause.ENDER_PEARL);
+                    Bukkit.getPluginManager().callEvent(teleEvent);
+
+                    if (!teleEvent.isCancelled() && entityplayer.connection.isAcceptingMessages()) {
+                        if (this.random.nextFloat() < 0.05F && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) {
+                            Endermite entityendermite = (Endermite) EntityType.ENDERMITE.create(this.level());
+
+                            if (entityendermite != null) {
+                                entityendermite.moveTo(entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
+                                this.level().addFreshEntity(entityendermite, CreatureSpawnEvent.SpawnReason.ENDER_PEARL);
+                            }
                         }
-                    }
 
-                    if (entity.isPassenger()) {
-                        serverPlayer.dismountTo(this.getX(), this.getY(), this.getZ());
-                    } else {
-                        entity.teleportTo(this.getX(), this.getY(), this.getZ());
-                    }
+                        if (entity.isPassenger()) {
+                            entity.stopRiding();
+                        }
 
-                    entity.resetFallDistance();
-                    entity.hurt(this.damageSources().fall(), 5.0F);
-                    this.level().playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS);
+                        entityplayer.connection.teleport(teleEvent.getTo());
+                        entity.resetFallDistance();
+                        entity.hurt(this.damageSources().fall().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
+                    }
+                    // CraftBukkit end
+                    this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS);
                 }
             } else if (entity != null) {
                 entity.teleportTo(this.getX(), this.getY(), this.getZ());
                 entity.resetFallDistance();
             }
 
-            this.discard();
+            this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
         }
+
     }
 
     @Override
     public void tick() {
         Entity entity = this.getOwner();
+
         if (entity instanceof ServerPlayer && !entity.isAlive() && this.level().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) {
-            this.discard();
+            this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
         } else {
             super.tick();
         }
+
     }
 
     @Nullable
     @Override
     public Entity changeDimension(ServerLevel destination) {
         Entity entity = this.getOwner();
-        if (entity != null && entity.level().dimension() != destination.dimension()) {
-            this.setOwner(null);
+
+        if (entity != null && destination != null && entity.level().dimension() != destination.dimension()) { // CraftBukkit - SPIGOT-6113
+            this.setOwner((Entity) null);
         }
 
         return super.changeDimension(destination);
