You can use dplyr::left_join to merge two data.frames as:
library(dplyr)
df1 %>% mutate(rn = row_number()) %>%
  left_join(df2, by = c("rn" = "index_df1")) %>%
  select(-rn)
#    x y.x  y.y
# 1 13   7 <NA>
# 2 14   8    a
# 3 15   9 <NA>
# 4 16  10    d
# 5 17  11    e
# 6 18  12    f
Updated: Based on feedback from OP. If rows are not sequential in df1 then an option could be as:
# Use `index_df1` to add a column having value of x in df1
df2$x <- df1[df2$index_df1,"x"]
# Now, merge
merge(df1, df2[,c("y", "x")], by.x = "x", by.y = "x", all.x = TRUE)
#    x y.x  y.y
# 1 13   7 <NA>
# 2 14   8    a
# 3 15   9 <NA>
# 4 16  10    d
# 5 17  11    e
# 6 18  12    f