case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
       return GOT_NORMAL;
 
     {
       asection *plt;
       const char *name;
+      bfd_vma addend = 0;
 
       if ((input_section->flags & SEC_ALLOC) == 0
          || h->plt.offset == (bfd_vma) -1)
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
          base_got = globals->root.sgot;
          off = h->got.offset;
            value = aarch64_calculate_got_entry_vma (h, globals, info,
                                                     value, output_bfd,
                                                     unresolved_reloc_p);
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+           addend = (globals->root.sgot->output_section->vma
+                     + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
-                                                      0, weak_undef_p);
+                                                      addend, weak_undef_p);
          return _bfd_aarch64_elf_put_addend (input_bfd, hit_data, bfd_r_type, howto, value);
        case BFD_RELOC_AARCH64_ADD_LO12:
        case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+    case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
       if (globals->root.sgot == NULL)
        BFD_ASSERT (h != NULL);
 
       if (h != NULL)
        {
+         bfd_vma addend = 0;
          value = aarch64_calculate_got_entry_vma (h, globals, info, value,
                                                   output_bfd,
                                                   unresolved_reloc_p);
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+           addend = (globals->root.sgot->output_section->vma
+                     + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
-                                                      0, weak_undef_p);
+                                                      addend, weak_undef_p);
        }
       else
       {
+       bfd_vma addend = 0;
        struct elf_aarch64_local_symbol *locals
          = elf_aarch64_locals (input_bfd);
 
        /* Update the relocation value to GOT entry addr as we have transformed
           the direct data access into indirect data access through GOT.  */
        value = got_entry_addr;
+
+       if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+         addend = base_got->output_section->vma + base_got->output_offset;
+
+       value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+                                                    addend, weak_undef_p);
       }
 
       break;
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
            case BFD_RELOC_AARCH64_GOT_LD_PREL19:
            case BFD_RELOC_AARCH64_JUMP26:
            case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+           case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
            case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
            case BFD_RELOC_AARCH64_NN:
              if (htab->root.dynobj == NULL)
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
+       case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
 
--- /dev/null
+#source: emit-relocs-313.s
+#ld: -T relocs.ld --defsym globala=0x11000 --defsym globalb=0x45000 --defsym globalc=0x1234  -e0 --emit-relocs
+#objdump: -dr
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0000000000010000 <\.text>:
+   10000:      90000082        adrp    x2, 20000 <_GLOBAL_OFFSET_TABLE_>
+                       10000: R_AARCH64_ADR_PREL_PG_HI21       _GLOBAL_OFFSET_TABLE_
+   10004:      f9400840        ldr     x0, \[x2,#16\]
+                       10004: R_AARCH64_LD64_GOTPAGE_LO15      globala
+   10008:      f9400c40        ldr     x0, \[x2,#24\]
+                       10008: R_AARCH64_LD64_GOTPAGE_LO15      globalb
+   1000c:      f9400440        ldr     x0, \[x2,#8\]
+                       1000c: R_AARCH64_LD64_GOTPAGE_LO15      globalc